blob: cab30c21025c759f171757b329cc938ab8626e92 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02009 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Antoine Pitrou346cbd32017-05-27 17:50:54 +020028#include "pythread.h"
Victor Stinner6036e442015-03-08 01:58:04 +010029#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020030#ifndef MS_WINDOWS
31#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010032#else
33#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020034#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000035
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020036/* On android API level 21, 'AT_EACCESS' is not declared although
37 * HAVE_FACCESSAT is defined. */
38#ifdef __ANDROID__
39#undef HAVE_FACCESSAT
40#endif
41
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000042#include <stdio.h> /* needed for ctermid() */
43
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000044#ifdef __cplusplus
45extern "C" {
46#endif
47
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000048PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000049"This module provides access to operating system functionality that is\n\
50standardized by the C Standard and the POSIX standard (a thinly\n\
51disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000052corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000054
Ross Lagerwall4d076da2011-03-18 06:56:53 +020055#ifdef HAVE_SYS_UIO_H
56#include <sys/uio.h>
57#endif
58
Christian Heimes75b96182017-09-05 15:53:09 +020059#ifdef HAVE_SYS_SYSMACROS_H
60/* GNU C Library: major(), minor(), makedev() */
61#include <sys/sysmacros.h>
62#endif
63
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000065#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#endif /* HAVE_SYS_TYPES_H */
67
68#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000069#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000071
Guido van Rossum36bc6801995-06-14 22:54:23 +000072#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000073#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000075
Thomas Wouters0e3f5912006-08-11 14:57:12 +000076#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000077#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000079
Guido van Rossumb6775db1994-08-01 11:34:53 +000080#ifdef HAVE_FCNTL_H
81#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000082#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000083
Guido van Rossuma6535fd2001-10-18 19:44:10 +000084#ifdef HAVE_GRP_H
85#include <grp.h>
86#endif
87
Barry Warsaw5676bd12003-01-07 20:57:09 +000088#ifdef HAVE_SYSEXITS_H
89#include <sysexits.h>
90#endif /* HAVE_SYSEXITS_H */
91
Anthony Baxter8a560de2004-10-13 15:30:56 +000092#ifdef HAVE_SYS_LOADAVG_H
93#include <sys/loadavg.h>
94#endif
95
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000096#ifdef HAVE_SYS_SENDFILE_H
97#include <sys/sendfile.h>
98#endif
99
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500100#ifdef HAVE_SCHED_H
101#include <sched.h>
102#endif
103
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500104#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500105#undef HAVE_SCHED_SETAFFINITY
106#endif
107
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200108#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400109#define USE_XATTRS
110#endif
111
112#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400113#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400114#endif
115
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000116#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
117#ifdef HAVE_SYS_SOCKET_H
118#include <sys/socket.h>
119#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000120#endif
121
Victor Stinner8b905bd2011-10-25 13:34:04 +0200122#ifdef HAVE_DLFCN_H
123#include <dlfcn.h>
124#endif
125
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200126#ifdef __hpux
127#include <sys/mpctl.h>
128#endif
129
130#if defined(__DragonFly__) || \
131 defined(__OpenBSD__) || \
132 defined(__FreeBSD__) || \
133 defined(__NetBSD__) || \
134 defined(__APPLE__)
135#include <sys/sysctl.h>
136#endif
137
Victor Stinner9b1f4742016-09-06 16:18:52 -0700138#ifdef HAVE_LINUX_RANDOM_H
139# include <linux/random.h>
140#endif
141#ifdef HAVE_GETRANDOM_SYSCALL
142# include <sys/syscall.h>
143#endif
144
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100145#if defined(MS_WINDOWS)
146# define TERMSIZE_USE_CONIO
147#elif defined(HAVE_SYS_IOCTL_H)
148# include <sys/ioctl.h>
149# if defined(HAVE_TERMIOS_H)
150# include <termios.h>
151# endif
152# if defined(TIOCGWINSZ)
153# define TERMSIZE_USE_IOCTL
154# endif
155#endif /* MS_WINDOWS */
156
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000158/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000161#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#include <process.h>
163#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000165#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000166#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700169#define HAVE_WSPAWNV 1
170#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000171#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000172#define HAVE_SYSTEM 1
173#define HAVE_CWAIT 1
174#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000175#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000176#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177/* Unix functions that the configure script doesn't check for */
178#define HAVE_EXECV 1
179#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000180#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000181#define HAVE_FORK1 1
182#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000183#define HAVE_GETEGID 1
184#define HAVE_GETEUID 1
185#define HAVE_GETGID 1
186#define HAVE_GETPPID 1
187#define HAVE_GETUID 1
188#define HAVE_KILL 1
189#define HAVE_OPENDIR 1
190#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000191#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000192#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000193#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000194#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000195#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000196
Victor Stinnera2f7c002012-02-08 03:36:25 +0100197
Larry Hastings61272b72014-01-07 12:41:53 -0800198/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000199# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800200module os
Larry Hastings61272b72014-01-07 12:41:53 -0800201[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000202/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100203
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000205
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000206#if defined(__sgi)&&_COMPILER_VERSION>=700
207/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
208 (default) */
209extern char *ctermid_r(char *);
210#endif
211
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000212#ifndef HAVE_UNISTD_H
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000213#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000214extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000216extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int chdir(char *);
220extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000221#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int chdir(const char *);
223extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000224#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000226/*#ifdef HAVE_FCHMOD
227extern int fchmod(int, mode_t);
228#endif*/
229/*#ifdef HAVE_LCHMOD
230extern int lchmod(const char *, mode_t);
231#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000232extern int chown(const char *, uid_t, gid_t);
233extern char *getcwd(char *, int);
234extern char *strerror(int);
235extern int link(const char *, const char *);
236extern int rename(const char *, const char *);
237extern int stat(const char *, struct stat *);
238extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000240extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000241#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000243extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000246
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000247#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#ifdef HAVE_UTIME_H
250#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000251#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000253#ifdef HAVE_SYS_UTIME_H
254#include <sys/utime.h>
255#define HAVE_UTIME_H /* pretend we do for the rest of this file */
256#endif /* HAVE_SYS_UTIME_H */
257
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#ifdef HAVE_SYS_TIMES_H
259#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000260#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261
262#ifdef HAVE_SYS_PARAM_H
263#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
266#ifdef HAVE_SYS_UTSNAME_H
267#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000268#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000270#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#define NAMLEN(dirent) strlen((dirent)->d_name)
273#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000274#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000275#include <direct.h>
276#define NAMLEN(dirent) strlen((dirent)->d_name)
277#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000280#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#endif
284#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000286#endif
287#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000288#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000289#endif
290#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000292#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000293#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#endif
296#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000297#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000298#endif
299#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000300#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000301#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000302#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000303#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100305#ifndef IO_REPARSE_TAG_MOUNT_POINT
306#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
307#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000308#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000309#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000311#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000312#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000313#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
314#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000315static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000316#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000317#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318
Tim Petersbc2e10e2002-03-03 23:17:02 +0000319#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320#if defined(PATH_MAX) && PATH_MAX > 1024
321#define MAXPATHLEN PATH_MAX
322#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000323#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000325#endif /* MAXPATHLEN */
326
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000327#ifdef UNION_WAIT
328/* Emulate some macros on systems that have a union instead of macros */
329
330#ifndef WIFEXITED
331#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
332#endif
333
334#ifndef WEXITSTATUS
335#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
336#endif
337
338#ifndef WTERMSIG
339#define WTERMSIG(u_wait) ((u_wait).w_termsig)
340#endif
341
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000342#define WAIT_TYPE union wait
343#define WAIT_STATUS_INT(s) (s.w_status)
344
345#else /* !UNION_WAIT */
346#define WAIT_TYPE int
347#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000348#endif /* UNION_WAIT */
349
Greg Wardb48bc172000-03-01 21:51:56 +0000350/* Don't use the "_r" form if we don't need it (also, won't have a
351 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200352#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000353#define USE_CTERMID_R
354#endif
355
Fred Drake699f3522000-06-29 21:12:41 +0000356/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000357#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000358#undef FSTAT
359#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200360#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000361# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700362# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200363# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800364# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000365#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000366# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700367# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000368# define FSTAT fstat
369# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000370#endif
371
Tim Peters11b23062003-04-23 02:39:17 +0000372#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000373#include <sys/mkdev.h>
374#else
375#if defined(MAJOR_IN_SYSMACROS)
376#include <sys/sysmacros.h>
377#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000378#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
379#include <sys/mkdev.h>
380#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000381#endif
Fred Drake699f3522000-06-29 21:12:41 +0000382
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200383#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100384#define INITFUNC PyInit_nt
385#define MODNAME "nt"
386#else
387#define INITFUNC PyInit_posix
388#define MODNAME "posix"
389#endif
390
jcea6c51d512018-01-28 14:00:08 +0100391#if defined(__sun)
392/* Something to implement in autoconf, not present in autoconf 2.69 */
393#define HAVE_STRUCT_STAT_ST_FSTYPE 1
394#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200395
396#ifdef HAVE_FORK
397static void
398run_at_forkers(PyObject *lst, int reverse)
399{
400 Py_ssize_t i;
401 PyObject *cpy;
402
403 if (lst != NULL) {
404 assert(PyList_CheckExact(lst));
405
406 /* Use a list copy in case register_at_fork() is called from
407 * one of the callbacks.
408 */
409 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
410 if (cpy == NULL)
411 PyErr_WriteUnraisable(lst);
412 else {
413 if (reverse)
414 PyList_Reverse(cpy);
415 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
416 PyObject *func, *res;
417 func = PyList_GET_ITEM(cpy, i);
418 res = PyObject_CallObject(func, NULL);
419 if (res == NULL)
420 PyErr_WriteUnraisable(func);
421 else
422 Py_DECREF(res);
423 }
424 Py_DECREF(cpy);
425 }
426 }
427}
428
429void
430PyOS_BeforeFork(void)
431{
432 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
433
434 _PyImport_AcquireLock();
435}
436
437void
438PyOS_AfterFork_Parent(void)
439{
440 if (_PyImport_ReleaseLock() <= 0)
441 Py_FatalError("failed releasing import lock after fork");
442
443 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
444}
445
446void
447PyOS_AfterFork_Child(void)
448{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200449 _PyGILState_Reinit();
450 PyEval_ReInitThreads();
451 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200452 _PySignal_AfterFork();
453
454 run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
455}
456
457static int
458register_at_forker(PyObject **lst, PyObject *func)
459{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700460 if (func == NULL) /* nothing to register? do nothing. */
461 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200462 if (*lst == NULL) {
463 *lst = PyList_New(0);
464 if (*lst == NULL)
465 return -1;
466 }
467 return PyList_Append(*lst, func);
468}
469#endif
470
471/* Legacy wrapper */
472void
473PyOS_AfterFork(void)
474{
475#ifdef HAVE_FORK
476 PyOS_AfterFork_Child();
477#endif
478}
479
480
Victor Stinner6036e442015-03-08 01:58:04 +0100481#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200482/* defined in fileutils.c */
483PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
484PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
485 ULONG, struct _Py_stat_struct *);
486#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700487
488#ifdef MS_WINDOWS
489static int
490win32_warn_bytes_api()
491{
492 return PyErr_WarnEx(PyExc_DeprecationWarning,
493 "The Windows bytes API has been deprecated, "
494 "use Unicode filenames instead",
495 1);
496}
497#endif
498
499
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200500#ifndef MS_WINDOWS
501PyObject *
502_PyLong_FromUid(uid_t uid)
503{
504 if (uid == (uid_t)-1)
505 return PyLong_FromLong(-1);
506 return PyLong_FromUnsignedLong(uid);
507}
508
509PyObject *
510_PyLong_FromGid(gid_t gid)
511{
512 if (gid == (gid_t)-1)
513 return PyLong_FromLong(-1);
514 return PyLong_FromUnsignedLong(gid);
515}
516
517int
518_Py_Uid_Converter(PyObject *obj, void *p)
519{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700520 uid_t uid;
521 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200522 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200523 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 unsigned long uresult;
525
526 index = PyNumber_Index(obj);
527 if (index == NULL) {
528 PyErr_Format(PyExc_TypeError,
529 "uid should be integer, not %.200s",
530 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200531 return 0;
532 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533
534 /*
535 * Handling uid_t is complicated for two reasons:
536 * * Although uid_t is (always?) unsigned, it still
537 * accepts -1.
538 * * We don't know its size in advance--it may be
539 * bigger than an int, or it may be smaller than
540 * a long.
541 *
542 * So a bit of defensive programming is in order.
543 * Start with interpreting the value passed
544 * in as a signed long and see if it works.
545 */
546
547 result = PyLong_AsLongAndOverflow(index, &overflow);
548
549 if (!overflow) {
550 uid = (uid_t)result;
551
552 if (result == -1) {
553 if (PyErr_Occurred())
554 goto fail;
555 /* It's a legitimate -1, we're done. */
556 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200557 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700558
559 /* Any other negative number is disallowed. */
560 if (result < 0)
561 goto underflow;
562
563 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200564 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700565 (long)uid != result)
566 goto underflow;
567 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200568 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700569
570 if (overflow < 0)
571 goto underflow;
572
573 /*
574 * Okay, the value overflowed a signed long. If it
575 * fits in an *unsigned* long, it may still be okay,
576 * as uid_t may be unsigned long on this platform.
577 */
578 uresult = PyLong_AsUnsignedLong(index);
579 if (PyErr_Occurred()) {
580 if (PyErr_ExceptionMatches(PyExc_OverflowError))
581 goto overflow;
582 goto fail;
583 }
584
585 uid = (uid_t)uresult;
586
587 /*
588 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
589 * but this value would get interpreted as (uid_t)-1 by chown
590 * and its siblings. That's not what the user meant! So we
591 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100592 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700593 */
594 if (uid == (uid_t)-1)
595 goto overflow;
596
597 /* Ensure the value wasn't truncated. */
598 if (sizeof(uid_t) < sizeof(long) &&
599 (unsigned long)uid != uresult)
600 goto overflow;
601 /* fallthrough */
602
603success:
604 Py_DECREF(index);
605 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200606 return 1;
607
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700608underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200609 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700610 "uid is less than minimum");
611 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200612
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700613overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200614 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700615 "uid is greater than maximum");
616 /* fallthrough */
617
618fail:
619 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620 return 0;
621}
622
623int
624_Py_Gid_Converter(PyObject *obj, void *p)
625{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700626 gid_t gid;
627 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200628 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200629 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700630 unsigned long uresult;
631
632 index = PyNumber_Index(obj);
633 if (index == NULL) {
634 PyErr_Format(PyExc_TypeError,
635 "gid should be integer, not %.200s",
636 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200637 return 0;
638 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700639
640 /*
641 * Handling gid_t is complicated for two reasons:
642 * * Although gid_t is (always?) unsigned, it still
643 * accepts -1.
644 * * We don't know its size in advance--it may be
645 * bigger than an int, or it may be smaller than
646 * a long.
647 *
648 * So a bit of defensive programming is in order.
649 * Start with interpreting the value passed
650 * in as a signed long and see if it works.
651 */
652
653 result = PyLong_AsLongAndOverflow(index, &overflow);
654
655 if (!overflow) {
656 gid = (gid_t)result;
657
658 if (result == -1) {
659 if (PyErr_Occurred())
660 goto fail;
661 /* It's a legitimate -1, we're done. */
662 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200663 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700664
665 /* Any other negative number is disallowed. */
666 if (result < 0) {
667 goto underflow;
668 }
669
670 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200671 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700672 (long)gid != result)
673 goto underflow;
674 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200675 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700676
677 if (overflow < 0)
678 goto underflow;
679
680 /*
681 * Okay, the value overflowed a signed long. If it
682 * fits in an *unsigned* long, it may still be okay,
683 * as gid_t may be unsigned long on this platform.
684 */
685 uresult = PyLong_AsUnsignedLong(index);
686 if (PyErr_Occurred()) {
687 if (PyErr_ExceptionMatches(PyExc_OverflowError))
688 goto overflow;
689 goto fail;
690 }
691
692 gid = (gid_t)uresult;
693
694 /*
695 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
696 * but this value would get interpreted as (gid_t)-1 by chown
697 * and its siblings. That's not what the user meant! So we
698 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100699 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700700 */
701 if (gid == (gid_t)-1)
702 goto overflow;
703
704 /* Ensure the value wasn't truncated. */
705 if (sizeof(gid_t) < sizeof(long) &&
706 (unsigned long)gid != uresult)
707 goto overflow;
708 /* fallthrough */
709
710success:
711 Py_DECREF(index);
712 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200713 return 1;
714
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700715underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200716 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700717 "gid is less than minimum");
718 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200719
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700720overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200721 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700722 "gid is greater than maximum");
723 /* fallthrough */
724
725fail:
726 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200727 return 0;
728}
729#endif /* MS_WINDOWS */
730
731
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700732#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800733
734
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200735#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
736static int
737_Py_Dev_Converter(PyObject *obj, void *p)
738{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200739 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200740 if (PyErr_Occurred())
741 return 0;
742 return 1;
743}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800744#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200745
746
Larry Hastings9cf065c2012-06-22 16:30:09 -0700747#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400748/*
749 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
750 * without the int cast, the value gets interpreted as uint (4291925331),
751 * which doesn't play nicely with all the initializer lines in this file that
752 * look like this:
753 * int dir_fd = DEFAULT_DIR_FD;
754 */
755#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700756#else
757#define DEFAULT_DIR_FD (-100)
758#endif
759
760static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300761_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200762{
763 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700764 long long_value;
765
766 PyObject *index = PyNumber_Index(o);
767 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700768 return 0;
769 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700770
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300771 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700772 long_value = PyLong_AsLongAndOverflow(index, &overflow);
773 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300774 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200775 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700776 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700777 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700778 return 0;
779 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200780 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700781 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700782 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700783 return 0;
784 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700785
Larry Hastings9cf065c2012-06-22 16:30:09 -0700786 *p = (int)long_value;
787 return 1;
788}
789
790static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200791dir_fd_converter(PyObject *o, void *p)
792{
793 if (o == Py_None) {
794 *(int *)p = DEFAULT_DIR_FD;
795 return 1;
796 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300797 else if (PyIndex_Check(o)) {
798 return _fd_converter(o, (int *)p);
799 }
800 else {
801 PyErr_Format(PyExc_TypeError,
802 "argument should be integer or None, not %.200s",
803 Py_TYPE(o)->tp_name);
804 return 0;
805 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700806}
807
808
Larry Hastings9cf065c2012-06-22 16:30:09 -0700809/*
810 * A PyArg_ParseTuple "converter" function
811 * that handles filesystem paths in the manner
812 * preferred by the os module.
813 *
814 * path_converter accepts (Unicode) strings and their
815 * subclasses, and bytes and their subclasses. What
816 * it does with the argument depends on the platform:
817 *
818 * * On Windows, if we get a (Unicode) string we
819 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700820 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700821 *
822 * * On all other platforms, strings are encoded
823 * to bytes using PyUnicode_FSConverter, then we
824 * extract the char * from the bytes object and
825 * return that.
826 *
827 * path_converter also optionally accepts signed
828 * integers (representing open file descriptors) instead
829 * of path strings.
830 *
831 * Input fields:
832 * path.nullable
833 * If nonzero, the path is permitted to be None.
834 * path.allow_fd
835 * If nonzero, the path is permitted to be a file handle
836 * (a signed int) instead of a string.
837 * path.function_name
838 * If non-NULL, path_converter will use that as the name
839 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700840 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700841 * path.argument_name
842 * If non-NULL, path_converter will use that as the name
843 * of the parameter in error messages.
844 * (If path.argument_name is NULL it uses "path".)
845 *
846 * Output fields:
847 * path.wide
848 * Points to the path if it was expressed as Unicode
849 * and was not encoded. (Only used on Windows.)
850 * path.narrow
851 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700852 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000853 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700854 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700855 * path.fd
856 * Contains a file descriptor if path.accept_fd was true
857 * and the caller provided a signed integer instead of any
858 * sort of string.
859 *
860 * WARNING: if your "path" parameter is optional, and is
861 * unspecified, path_converter will never get called.
862 * So if you set allow_fd, you *MUST* initialize path.fd = -1
863 * yourself!
864 * path.length
865 * The length of the path in characters, if specified as
866 * a string.
867 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800868 * The original object passed in (if get a PathLike object,
869 * the result of PyOS_FSPath() is treated as the original object).
870 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700871 * path.cleanup
872 * For internal use only. May point to a temporary object.
873 * (Pay no attention to the man behind the curtain.)
874 *
875 * At most one of path.wide or path.narrow will be non-NULL.
876 * If path was None and path.nullable was set,
877 * or if path was an integer and path.allow_fd was set,
878 * both path.wide and path.narrow will be NULL
879 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200880 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700881 * path_converter takes care to not write to the path_t
882 * unless it's successful. However it must reset the
883 * "cleanup" field each time it's called.
884 *
885 * Use as follows:
886 * path_t path;
887 * memset(&path, 0, sizeof(path));
888 * PyArg_ParseTuple(args, "O&", path_converter, &path);
889 * // ... use values from path ...
890 * path_cleanup(&path);
891 *
892 * (Note that if PyArg_Parse fails you don't need to call
893 * path_cleanup(). However it is safe to do so.)
894 */
895typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100896 const char *function_name;
897 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700898 int nullable;
899 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300900 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700901#ifdef MS_WINDOWS
902 BOOL narrow;
903#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300904 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700905#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700906 int fd;
907 Py_ssize_t length;
908 PyObject *object;
909 PyObject *cleanup;
910} path_t;
911
Steve Dowercc16be82016-09-08 10:35:16 -0700912#ifdef MS_WINDOWS
913#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
914 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
915#else
Larry Hastings2f936352014-08-05 14:04:04 +1000916#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
917 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700918#endif
Larry Hastings31826802013-10-19 00:09:25 -0700919
Larry Hastings9cf065c2012-06-22 16:30:09 -0700920static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800921path_cleanup(path_t *path)
922{
923 Py_CLEAR(path->object);
924 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700925}
926
927static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300928path_converter(PyObject *o, void *p)
929{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700930 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800931 PyObject *bytes = NULL;
932 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700933 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300934 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700935#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800936 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700937 const wchar_t *wide;
938#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700939
940#define FORMAT_EXCEPTION(exc, fmt) \
941 PyErr_Format(exc, "%s%s" fmt, \
942 path->function_name ? path->function_name : "", \
943 path->function_name ? ": " : "", \
944 path->argument_name ? path->argument_name : "path")
945
946 /* Py_CLEANUP_SUPPORTED support */
947 if (o == NULL) {
948 path_cleanup(path);
949 return 1;
950 }
951
Brett Cannon3f9183b2016-08-26 14:44:48 -0700952 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800953 path->object = path->cleanup = NULL;
954 /* path->object owns a reference to the original object */
955 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700956
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300957 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700958 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700959#ifdef MS_WINDOWS
960 path->narrow = FALSE;
961#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700962 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700963#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800965 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 }
967
Brett Cannon3f9183b2016-08-26 14:44:48 -0700968 /* Only call this here so that we don't treat the return value of
969 os.fspath() as an fd or buffer. */
970 is_index = path->allow_fd && PyIndex_Check(o);
971 is_buffer = PyObject_CheckBuffer(o);
972 is_bytes = PyBytes_Check(o);
973 is_unicode = PyUnicode_Check(o);
974
975 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
976 /* Inline PyOS_FSPath() for better error messages. */
977 _Py_IDENTIFIER(__fspath__);
978 PyObject *func = NULL;
979
980 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
981 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800982 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700983 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800984 /* still owns a reference to the original object */
985 Py_DECREF(o);
986 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700987 Py_DECREF(func);
988 if (NULL == o) {
989 goto error_exit;
990 }
991 else if (PyUnicode_Check(o)) {
992 is_unicode = 1;
993 }
994 else if (PyBytes_Check(o)) {
995 is_bytes = 1;
996 }
997 else {
Xiang Zhang04316c42017-01-08 23:26:57 +0800998 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700999 }
1000 }
1001
1002 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001003#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001004 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001005 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001006 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007 }
Victor Stinner59799a82013-11-13 14:17:30 +01001008 if (length > 32767) {
1009 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001010 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001011 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001012 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001013 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001014 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001015 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001016
1017 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001018 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001019 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001020 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001021#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001022 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001023 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001024 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001025#endif
1026 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001027 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001028 bytes = o;
1029 Py_INCREF(bytes);
1030 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001031 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001032 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001033 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001034 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1035 "%s%s%s should be %s, not %.200s",
1036 path->function_name ? path->function_name : "",
1037 path->function_name ? ": " : "",
1038 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001039 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1040 "integer or None" :
1041 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1042 path->nullable ? "string, bytes, os.PathLike or None" :
1043 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001044 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001045 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001046 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001047 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001048 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001049 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001050 }
1051 }
Steve Dowercc16be82016-09-08 10:35:16 -07001052 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001053 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001054 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001055 }
1056 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001057#ifdef MS_WINDOWS
1058 path->narrow = FALSE;
1059#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001060 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001061#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001062 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001063 }
1064 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001065 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001066 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1067 path->function_name ? path->function_name : "",
1068 path->function_name ? ": " : "",
1069 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001070 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1071 "integer or None" :
1072 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1073 path->nullable ? "string, bytes, os.PathLike or None" :
1074 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001075 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001076 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001077 }
1078
Larry Hastings9cf065c2012-06-22 16:30:09 -07001079 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001080 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001081 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001082 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001083 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 }
1085
Steve Dowercc16be82016-09-08 10:35:16 -07001086#ifdef MS_WINDOWS
1087 wo = PyUnicode_DecodeFSDefaultAndSize(
1088 narrow,
1089 length
1090 );
1091 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001092 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001093 }
1094
Xiang Zhang04316c42017-01-08 23:26:57 +08001095 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001096 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001097 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001098 }
1099 if (length > 32767) {
1100 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001101 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001102 }
1103 if (wcslen(wide) != length) {
1104 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001105 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001106 }
1107 path->wide = wide;
1108 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001109 path->cleanup = wo;
1110 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001111#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001112 path->wide = NULL;
1113 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001114 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001115 /* Still a reference owned by path->object, don't have to
1116 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001117 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001118 }
1119 else {
1120 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001121 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001122#endif
1123 path->fd = -1;
1124
1125 success_exit:
1126 path->length = length;
1127 path->object = o;
1128 return Py_CLEANUP_SUPPORTED;
1129
1130 error_exit:
1131 Py_XDECREF(o);
1132 Py_XDECREF(bytes);
1133#ifdef MS_WINDOWS
1134 Py_XDECREF(wo);
1135#endif
1136 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001137}
1138
1139static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001140argument_unavailable_error(const char *function_name, const char *argument_name)
1141{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001142 PyErr_Format(PyExc_NotImplementedError,
1143 "%s%s%s unavailable on this platform",
1144 (function_name != NULL) ? function_name : "",
1145 (function_name != NULL) ? ": ": "",
1146 argument_name);
1147}
1148
1149static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001150dir_fd_unavailable(PyObject *o, void *p)
1151{
1152 int dir_fd;
1153 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001154 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001155 if (dir_fd != DEFAULT_DIR_FD) {
1156 argument_unavailable_error(NULL, "dir_fd");
1157 return 0;
1158 }
1159 *(int *)p = dir_fd;
1160 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001161}
1162
1163static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001164fd_specified(const char *function_name, int fd)
1165{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001166 if (fd == -1)
1167 return 0;
1168
1169 argument_unavailable_error(function_name, "fd");
1170 return 1;
1171}
1172
1173static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001174follow_symlinks_specified(const char *function_name, int follow_symlinks)
1175{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001176 if (follow_symlinks)
1177 return 0;
1178
1179 argument_unavailable_error(function_name, "follow_symlinks");
1180 return 1;
1181}
1182
1183static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001184path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1185{
Steve Dowercc16be82016-09-08 10:35:16 -07001186 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1187#ifndef MS_WINDOWS
1188 && !path->narrow
1189#endif
1190 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001191 PyErr_Format(PyExc_ValueError,
1192 "%s: can't specify dir_fd without matching path",
1193 function_name);
1194 return 1;
1195 }
1196 return 0;
1197}
1198
1199static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001200dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1201{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001202 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1203 PyErr_Format(PyExc_ValueError,
1204 "%s: can't specify both dir_fd and fd",
1205 function_name);
1206 return 1;
1207 }
1208 return 0;
1209}
1210
1211static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001212fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1213 int follow_symlinks)
1214{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001215 if ((fd > 0) && (!follow_symlinks)) {
1216 PyErr_Format(PyExc_ValueError,
1217 "%s: cannot use fd and follow_symlinks together",
1218 function_name);
1219 return 1;
1220 }
1221 return 0;
1222}
1223
1224static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001225dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1226 int follow_symlinks)
1227{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001228 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1229 PyErr_Format(PyExc_ValueError,
1230 "%s: cannot use dir_fd and follow_symlinks together",
1231 function_name);
1232 return 1;
1233 }
1234 return 0;
1235}
1236
Larry Hastings2f936352014-08-05 14:04:04 +10001237#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001238 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001239#else
Larry Hastings2f936352014-08-05 14:04:04 +10001240 typedef off_t Py_off_t;
1241#endif
1242
1243static int
1244Py_off_t_converter(PyObject *arg, void *addr)
1245{
1246#ifdef HAVE_LARGEFILE_SUPPORT
1247 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1248#else
1249 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001250#endif
1251 if (PyErr_Occurred())
1252 return 0;
1253 return 1;
1254}
Larry Hastings2f936352014-08-05 14:04:04 +10001255
1256static PyObject *
1257PyLong_FromPy_off_t(Py_off_t offset)
1258{
1259#ifdef HAVE_LARGEFILE_SUPPORT
1260 return PyLong_FromLongLong(offset);
1261#else
1262 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001263#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001264}
1265
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001266#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001267
1268static int
Brian Curtind25aef52011-06-13 15:16:04 -05001269win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001270{
Martin Panter70214ad2016-08-04 02:38:59 +00001271 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1272 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001273 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001274
1275 if (0 == DeviceIoControl(
1276 reparse_point_handle,
1277 FSCTL_GET_REPARSE_POINT,
1278 NULL, 0, /* in buffer */
1279 target_buffer, sizeof(target_buffer),
1280 &n_bytes_returned,
1281 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001282 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001283
1284 if (reparse_tag)
1285 *reparse_tag = rdb->ReparseTag;
1286
Brian Curtind25aef52011-06-13 15:16:04 -05001287 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001288}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001289
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001290#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001291
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001293#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001294/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001295** environ directly, we must obtain it with _NSGetEnviron(). See also
1296** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001297*/
1298#include <crt_externs.h>
1299static char **environ;
1300#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001301extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001302#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303
Barry Warsaw53699e91996-12-10 23:23:01 +00001304static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001305convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001306{
Victor Stinner8c62be82010-05-06 00:08:46 +00001307 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001308#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001309 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001310#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001312#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001313
Victor Stinner8c62be82010-05-06 00:08:46 +00001314 d = PyDict_New();
1315 if (d == NULL)
1316 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001317#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001318 if (environ == NULL)
1319 environ = *_NSGetEnviron();
1320#endif
1321#ifdef MS_WINDOWS
1322 /* _wenviron must be initialized in this way if the program is started
1323 through main() instead of wmain(). */
1324 _wgetenv(L"");
1325 if (_wenviron == NULL)
1326 return d;
1327 /* This part ignores errors */
1328 for (e = _wenviron; *e != NULL; e++) {
1329 PyObject *k;
1330 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001331 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001332 if (p == NULL)
1333 continue;
1334 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1335 if (k == NULL) {
1336 PyErr_Clear();
1337 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001338 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001339 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1340 if (v == NULL) {
1341 PyErr_Clear();
1342 Py_DECREF(k);
1343 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001344 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001345 if (PyDict_GetItem(d, k) == NULL) {
1346 if (PyDict_SetItem(d, k, v) != 0)
1347 PyErr_Clear();
1348 }
1349 Py_DECREF(k);
1350 Py_DECREF(v);
1351 }
1352#else
1353 if (environ == NULL)
1354 return d;
1355 /* This part ignores errors */
1356 for (e = environ; *e != NULL; e++) {
1357 PyObject *k;
1358 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001359 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001360 if (p == NULL)
1361 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001362 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 if (k == NULL) {
1364 PyErr_Clear();
1365 continue;
1366 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001367 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 if (v == NULL) {
1369 PyErr_Clear();
1370 Py_DECREF(k);
1371 continue;
1372 }
1373 if (PyDict_GetItem(d, k) == NULL) {
1374 if (PyDict_SetItem(d, k, v) != 0)
1375 PyErr_Clear();
1376 }
1377 Py_DECREF(k);
1378 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001379 }
1380#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001382}
1383
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001384/* Set a POSIX-specific error from errno, and return NULL */
1385
Barry Warsawd58d7641998-07-23 16:14:40 +00001386static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001387posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001388{
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001390}
Mark Hammondef8b6542001-05-13 08:04:26 +00001391
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001392#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001393static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001394win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001395{
Victor Stinner8c62be82010-05-06 00:08:46 +00001396 /* XXX We should pass the function name along in the future.
1397 (winreg.c also wants to pass the function name.)
1398 This would however require an additional param to the
1399 Windows error object, which is non-trivial.
1400 */
1401 errno = GetLastError();
1402 if (filename)
1403 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1404 else
1405 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001406}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001407
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001408static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001409win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001410{
1411 /* XXX - see win32_error for comments on 'function' */
1412 errno = GetLastError();
1413 if (filename)
1414 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001415 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001416 errno,
1417 filename);
1418 else
1419 return PyErr_SetFromWindowsErr(errno);
1420}
1421
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001422#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001423
Larry Hastings9cf065c2012-06-22 16:30:09 -07001424static PyObject *
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001425posix_path_object_error(PyObject *path)
1426{
1427 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1428}
1429
1430static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001431path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001432{
1433#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001434 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1435 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001436#else
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001437 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001438#endif
1439}
1440
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001441static PyObject *
1442path_object_error2(PyObject *path, PyObject *path2)
1443{
1444#ifdef MS_WINDOWS
1445 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1446 PyExc_OSError, 0, path, path2);
1447#else
1448 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1449#endif
1450}
1451
1452static PyObject *
1453path_error(path_t *path)
1454{
1455 return path_object_error(path->object);
1456}
Larry Hastings31826802013-10-19 00:09:25 -07001457
Larry Hastingsb0827312014-02-09 22:05:19 -08001458static PyObject *
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001459posix_path_error(path_t *path)
1460{
1461 return posix_path_object_error(path->object);
1462}
1463
1464static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001465path_error2(path_t *path, path_t *path2)
1466{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001467 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001468}
1469
1470
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001471/* POSIX generic methods */
1472
Larry Hastings2f936352014-08-05 14:04:04 +10001473static int
1474fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001475{
Victor Stinner8c62be82010-05-06 00:08:46 +00001476 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001477 int *pointer = (int *)p;
1478 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001479 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001480 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001481 *pointer = fd;
1482 return 1;
1483}
1484
1485static PyObject *
1486posix_fildes_fd(int fd, int (*func)(int))
1487{
1488 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001489 int async_err = 0;
1490
1491 do {
1492 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001493 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001494 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001495 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001496 Py_END_ALLOW_THREADS
1497 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1498 if (res != 0)
1499 return (!async_err) ? posix_error() : NULL;
1500 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001501}
Guido van Rossum21142a01999-01-08 21:05:37 +00001502
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001503
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001504#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505/* This is a reimplementation of the C library's chdir function,
1506 but one that produces Win32 errors instead of DOS error codes.
1507 chdir is essentially a wrapper around SetCurrentDirectory; however,
1508 it also needs to set "magic" environment variables indicating
1509 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001510static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001511win32_wchdir(LPCWSTR path)
1512{
Victor Stinnered537822015-12-13 21:40:26 +01001513 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 int result;
1515 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001516
Victor Stinner8c62be82010-05-06 00:08:46 +00001517 if(!SetCurrentDirectoryW(path))
1518 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001519 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001520 if (!result)
1521 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001522 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001523 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001524 if (!new_path) {
1525 SetLastError(ERROR_OUTOFMEMORY);
1526 return FALSE;
1527 }
1528 result = GetCurrentDirectoryW(result, new_path);
1529 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001530 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001531 return FALSE;
1532 }
1533 }
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001534 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1535 wcsncmp(new_path, L"//", 2) == 0);
1536 if (!is_unc_like_path) {
1537 env[1] = new_path[0];
1538 result = SetEnvironmentVariableW(env, new_path);
1539 }
Victor Stinnered537822015-12-13 21:40:26 +01001540 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001541 PyMem_RawFree(new_path);
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001542 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001543}
1544#endif
1545
Martin v. Löwis14694662006-02-03 12:54:16 +00001546#ifdef MS_WINDOWS
1547/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1548 - time stamps are restricted to second resolution
1549 - file modification times suffer from forth-and-back conversions between
1550 UTC and local time
1551 Therefore, we implement our own stat, based on the Win32 API directly.
1552*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001553#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001554#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001555
Victor Stinner6036e442015-03-08 01:58:04 +01001556static void
Steve Dowercc16be82016-09-08 10:35:16 -07001557find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1558 BY_HANDLE_FILE_INFORMATION *info,
1559 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001560{
1561 memset(info, 0, sizeof(*info));
1562 info->dwFileAttributes = pFileData->dwFileAttributes;
1563 info->ftCreationTime = pFileData->ftCreationTime;
1564 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1565 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1566 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1567 info->nFileSizeLow = pFileData->nFileSizeLow;
1568/* info->nNumberOfLinks = 1; */
1569 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1570 *reparse_tag = pFileData->dwReserved0;
1571 else
1572 *reparse_tag = 0;
1573}
1574
Guido van Rossumd8faa362007-04-27 19:54:29 +00001575static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001576attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001577{
Victor Stinner8c62be82010-05-06 00:08:46 +00001578 HANDLE hFindFile;
1579 WIN32_FIND_DATAW FileData;
1580 hFindFile = FindFirstFileW(pszFile, &FileData);
1581 if (hFindFile == INVALID_HANDLE_VALUE)
1582 return FALSE;
1583 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001584 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001585 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001586}
1587
Brian Curtind25aef52011-06-13 15:16:04 -05001588static BOOL
1589get_target_path(HANDLE hdl, wchar_t **target_path)
1590{
1591 int buf_size, result_length;
1592 wchar_t *buf;
1593
1594 /* We have a good handle to the target, use it to determine
1595 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001596 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1597 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001598 if(!buf_size)
1599 return FALSE;
1600
Victor Stinnerc36674a2016-03-16 14:30:16 +01001601 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001602 if (!buf) {
1603 SetLastError(ERROR_OUTOFMEMORY);
1604 return FALSE;
1605 }
1606
Steve Dower2ea51c92015-03-20 21:49:12 -07001607 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001608 buf, buf_size, VOLUME_NAME_DOS);
1609
1610 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001611 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001612 return FALSE;
1613 }
1614
1615 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001616 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001617 return FALSE;
1618 }
1619
1620 buf[result_length] = 0;
1621
1622 *target_path = buf;
1623 return TRUE;
1624}
1625
1626static int
Steve Dowercc16be82016-09-08 10:35:16 -07001627win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001628 BOOL traverse)
1629{
Victor Stinner26de69d2011-06-17 15:15:38 +02001630 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001631 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001632 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001633 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001634 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001635 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001636
Steve Dowercc16be82016-09-08 10:35:16 -07001637 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001638 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001639 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001640 0, /* share mode */
1641 NULL, /* security attributes */
1642 OPEN_EXISTING,
1643 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001644 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1645 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001646 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001647 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1648 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001649 NULL);
1650
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001651 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001652 /* Either the target doesn't exist, or we don't have access to
1653 get a handle to it. If the former, we need to return an error.
1654 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001655 DWORD lastError = GetLastError();
1656 if (lastError != ERROR_ACCESS_DENIED &&
1657 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001658 return -1;
1659 /* Could not get attributes on open file. Fall back to
1660 reading the directory. */
1661 if (!attributes_from_dir(path, &info, &reparse_tag))
1662 /* Very strange. This should not fail now */
1663 return -1;
1664 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1665 if (traverse) {
1666 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001667 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001668 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001669 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001670 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001671 } else {
1672 if (!GetFileInformationByHandle(hFile, &info)) {
1673 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001674 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001675 }
1676 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001677 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1678 return -1;
1679
1680 /* Close the outer open file handle now that we're about to
1681 reopen it with different flags. */
1682 if (!CloseHandle(hFile))
1683 return -1;
1684
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001685 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001686 /* In order to call GetFinalPathNameByHandle we need to open
1687 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001688 hFile2 = CreateFileW(
1689 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1690 NULL, OPEN_EXISTING,
1691 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1692 NULL);
1693 if (hFile2 == INVALID_HANDLE_VALUE)
1694 return -1;
1695
1696 if (!get_target_path(hFile2, &target_path))
1697 return -1;
1698
Steve Dowercc16be82016-09-08 10:35:16 -07001699 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001700 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001701 return code;
1702 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001703 } else
1704 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001706 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001707
1708 /* Set S_IEXEC if it is an .exe, .bat, ... */
1709 dot = wcsrchr(path, '.');
1710 if (dot) {
1711 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1712 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1713 result->st_mode |= 0111;
1714 }
1715 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001716}
1717
1718static int
Steve Dowercc16be82016-09-08 10:35:16 -07001719win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001720{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001721 /* Protocol violation: we explicitly clear errno, instead of
1722 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001723 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001724 errno = 0;
1725 return code;
1726}
Brian Curtind25aef52011-06-13 15:16:04 -05001727/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001728
1729 In Posix, stat automatically traverses symlinks and returns the stat
1730 structure for the target. In Windows, the equivalent GetFileAttributes by
1731 default does not traverse symlinks and instead returns attributes for
1732 the symlink.
1733
1734 Therefore, win32_lstat will get the attributes traditionally, and
1735 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001736 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001737
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001738static int
Steve Dowercc16be82016-09-08 10:35:16 -07001739win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001740{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001741 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001742}
1743
Victor Stinner8c62be82010-05-06 00:08:46 +00001744static int
Steve Dowercc16be82016-09-08 10:35:16 -07001745win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001746{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001747 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001748}
1749
Martin v. Löwis14694662006-02-03 12:54:16 +00001750#endif /* MS_WINDOWS */
1751
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001752PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001753"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001754This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001755 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001756or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1757\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001758Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1759or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001760\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001761See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001762
1763static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 {"st_mode", "protection bits"},
1765 {"st_ino", "inode"},
1766 {"st_dev", "device"},
1767 {"st_nlink", "number of hard links"},
1768 {"st_uid", "user ID of owner"},
1769 {"st_gid", "group ID of owner"},
1770 {"st_size", "total size, in bytes"},
1771 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1772 {NULL, "integer time of last access"},
1773 {NULL, "integer time of last modification"},
1774 {NULL, "integer time of last change"},
1775 {"st_atime", "time of last access"},
1776 {"st_mtime", "time of last modification"},
1777 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001778 {"st_atime_ns", "time of last access in nanoseconds"},
1779 {"st_mtime_ns", "time of last modification in nanoseconds"},
1780 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001781#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001783#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001784#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001786#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001787#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001789#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001790#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001791 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001792#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001793#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001794 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001795#endif
1796#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001798#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001799#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1800 {"st_file_attributes", "Windows file attribute bits"},
1801#endif
jcea6c51d512018-01-28 14:00:08 +01001802#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1803 {"st_fstype", "Type of filesystem"},
1804#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001805 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001806};
1807
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001808#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001809#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001810#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001811#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001812#endif
1813
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001814#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001815#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1816#else
1817#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1818#endif
1819
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001820#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001821#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1822#else
1823#define ST_RDEV_IDX ST_BLOCKS_IDX
1824#endif
1825
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001826#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1827#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1828#else
1829#define ST_FLAGS_IDX ST_RDEV_IDX
1830#endif
1831
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001832#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001833#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001834#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001835#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001836#endif
1837
1838#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1839#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1840#else
1841#define ST_BIRTHTIME_IDX ST_GEN_IDX
1842#endif
1843
Zachary Ware63f277b2014-06-19 09:46:37 -05001844#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1845#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1846#else
1847#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1848#endif
1849
jcea6c51d512018-01-28 14:00:08 +01001850#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1851#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1852#else
1853#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1854#endif
1855
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001856static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001857 "stat_result", /* name */
1858 stat_result__doc__, /* doc */
1859 stat_result_fields,
1860 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001861};
1862
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001863PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001864"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1865This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001866 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001867or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001868\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001870
1871static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001872 {"f_bsize", },
1873 {"f_frsize", },
1874 {"f_blocks", },
1875 {"f_bfree", },
1876 {"f_bavail", },
1877 {"f_files", },
1878 {"f_ffree", },
1879 {"f_favail", },
1880 {"f_flag", },
1881 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001882 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001883 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001884};
1885
1886static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001887 "statvfs_result", /* name */
1888 statvfs_result__doc__, /* doc */
1889 statvfs_result_fields,
1890 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001891};
1892
Ross Lagerwall7807c352011-03-17 20:20:30 +02001893#if defined(HAVE_WAITID) && !defined(__APPLE__)
1894PyDoc_STRVAR(waitid_result__doc__,
1895"waitid_result: Result from waitid.\n\n\
1896This object may be accessed either as a tuple of\n\
1897 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1898or via the attributes si_pid, si_uid, and so on.\n\
1899\n\
1900See os.waitid for more information.");
1901
1902static PyStructSequence_Field waitid_result_fields[] = {
1903 {"si_pid", },
1904 {"si_uid", },
1905 {"si_signo", },
1906 {"si_status", },
1907 {"si_code", },
1908 {0}
1909};
1910
1911static PyStructSequence_Desc waitid_result_desc = {
1912 "waitid_result", /* name */
1913 waitid_result__doc__, /* doc */
1914 waitid_result_fields,
1915 5
1916};
1917static PyTypeObject WaitidResultType;
1918#endif
1919
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001920static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001921static PyTypeObject StatResultType;
1922static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001923#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001924static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001925#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001926static newfunc structseq_new;
1927
1928static PyObject *
1929statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1930{
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 PyStructSequence *result;
1932 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001933
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 result = (PyStructSequence*)structseq_new(type, args, kwds);
1935 if (!result)
1936 return NULL;
1937 /* If we have been initialized from a tuple,
1938 st_?time might be set to None. Initialize it
1939 from the int slots. */
1940 for (i = 7; i <= 9; i++) {
1941 if (result->ob_item[i+3] == Py_None) {
1942 Py_DECREF(Py_None);
1943 Py_INCREF(result->ob_item[i]);
1944 result->ob_item[i+3] = result->ob_item[i];
1945 }
1946 }
1947 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001948}
1949
1950
Larry Hastings6fe20b32012-04-19 15:07:49 -07001951static PyObject *billion = NULL;
1952
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001953static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001954fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001955{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001956 PyObject *s = _PyLong_FromTime_t(sec);
1957 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1958 PyObject *s_in_ns = NULL;
1959 PyObject *ns_total = NULL;
1960 PyObject *float_s = NULL;
1961
1962 if (!(s && ns_fractional))
1963 goto exit;
1964
1965 s_in_ns = PyNumber_Multiply(s, billion);
1966 if (!s_in_ns)
1967 goto exit;
1968
1969 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1970 if (!ns_total)
1971 goto exit;
1972
Victor Stinner01b5aab2017-10-24 02:02:00 -07001973 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1974 if (!float_s) {
1975 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07001976 }
1977
1978 PyStructSequence_SET_ITEM(v, index, s);
1979 PyStructSequence_SET_ITEM(v, index+3, float_s);
1980 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1981 s = NULL;
1982 float_s = NULL;
1983 ns_total = NULL;
1984exit:
1985 Py_XDECREF(s);
1986 Py_XDECREF(ns_fractional);
1987 Py_XDECREF(s_in_ns);
1988 Py_XDECREF(ns_total);
1989 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001990}
1991
Tim Peters5aa91602002-01-30 05:46:57 +00001992/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001993 (used by posix_stat() and posix_fstat()) */
1994static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001995_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001996{
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 unsigned long ansec, mnsec, cnsec;
1998 PyObject *v = PyStructSequence_New(&StatResultType);
1999 if (v == NULL)
2000 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002001
Victor Stinner8c62be82010-05-06 00:08:46 +00002002 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002003 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002004 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002005#ifdef MS_WINDOWS
2006 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002007#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002008 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002009#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002011#if defined(MS_WINDOWS)
2012 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2013 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2014#else
2015 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2016 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2017#endif
xdegaye50e86032017-05-22 11:15:08 +02002018 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2019 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002020
Martin v. Löwis14694662006-02-03 12:54:16 +00002021#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 ansec = st->st_atim.tv_nsec;
2023 mnsec = st->st_mtim.tv_nsec;
2024 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002025#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 ansec = st->st_atimespec.tv_nsec;
2027 mnsec = st->st_mtimespec.tv_nsec;
2028 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002029#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002030 ansec = st->st_atime_nsec;
2031 mnsec = st->st_mtime_nsec;
2032 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002033#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002035#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002036 fill_time(v, 7, st->st_atime, ansec);
2037 fill_time(v, 8, st->st_mtime, mnsec);
2038 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002039
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002040#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2042 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002043#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002044#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2046 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002047#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002048#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2050 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002051#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002052#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2054 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002055#endif
2056#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002058 PyObject *val;
2059 unsigned long bsec,bnsec;
2060 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002061#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002062 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002063#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002064 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002065#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002066 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002067 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2068 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002070#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002071#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002072 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2073 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002074#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002075#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2076 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2077 PyLong_FromUnsignedLong(st->st_file_attributes));
2078#endif
jcea6c51d512018-01-28 14:00:08 +01002079#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2080 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2081 PyUnicode_FromString(st->st_fstype));
2082#endif
Fred Drake699f3522000-06-29 21:12:41 +00002083
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 if (PyErr_Occurred()) {
2085 Py_DECREF(v);
2086 return NULL;
2087 }
Fred Drake699f3522000-06-29 21:12:41 +00002088
Victor Stinner8c62be82010-05-06 00:08:46 +00002089 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002090}
2091
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002092/* POSIX methods */
2093
Guido van Rossum94f6f721999-01-06 18:42:14 +00002094
2095static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002096posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002097 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002098{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002099 STRUCT_STAT st;
2100 int result;
2101
2102#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2103 if (follow_symlinks_specified(function_name, follow_symlinks))
2104 return NULL;
2105#endif
2106
2107 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2108 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2109 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2110 return NULL;
2111
2112 Py_BEGIN_ALLOW_THREADS
2113 if (path->fd != -1)
2114 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002115#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002116 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002117 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002118 else
Steve Dowercc16be82016-09-08 10:35:16 -07002119 result = win32_lstat(path->wide, &st);
2120#else
2121 else
2122#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002123 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2124 result = LSTAT(path->narrow, &st);
2125 else
Steve Dowercc16be82016-09-08 10:35:16 -07002126#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002127#ifdef HAVE_FSTATAT
2128 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2129 result = fstatat(dir_fd, path->narrow, &st,
2130 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2131 else
Steve Dowercc16be82016-09-08 10:35:16 -07002132#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002133 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002134#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002135 Py_END_ALLOW_THREADS
2136
Victor Stinner292c8352012-10-30 02:17:38 +01002137 if (result != 0) {
2138 return path_error(path);
2139 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002140
2141 return _pystat_fromstructstat(&st);
2142}
2143
Larry Hastings2f936352014-08-05 14:04:04 +10002144/*[python input]
2145
2146for s in """
2147
2148FACCESSAT
2149FCHMODAT
2150FCHOWNAT
2151FSTATAT
2152LINKAT
2153MKDIRAT
2154MKFIFOAT
2155MKNODAT
2156OPENAT
2157READLINKAT
2158SYMLINKAT
2159UNLINKAT
2160
2161""".strip().split():
2162 s = s.strip()
2163 print("""
2164#ifdef HAVE_{s}
2165 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002166#else
Larry Hastings2f936352014-08-05 14:04:04 +10002167 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002168#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002169""".rstrip().format(s=s))
2170
2171for s in """
2172
2173FCHDIR
2174FCHMOD
2175FCHOWN
2176FDOPENDIR
2177FEXECVE
2178FPATHCONF
2179FSTATVFS
2180FTRUNCATE
2181
2182""".strip().split():
2183 s = s.strip()
2184 print("""
2185#ifdef HAVE_{s}
2186 #define PATH_HAVE_{s} 1
2187#else
2188 #define PATH_HAVE_{s} 0
2189#endif
2190
2191""".rstrip().format(s=s))
2192[python start generated code]*/
2193
2194#ifdef HAVE_FACCESSAT
2195 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2196#else
2197 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2198#endif
2199
2200#ifdef HAVE_FCHMODAT
2201 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2202#else
2203 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2204#endif
2205
2206#ifdef HAVE_FCHOWNAT
2207 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2208#else
2209 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2210#endif
2211
2212#ifdef HAVE_FSTATAT
2213 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2214#else
2215 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2216#endif
2217
2218#ifdef HAVE_LINKAT
2219 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2220#else
2221 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2222#endif
2223
2224#ifdef HAVE_MKDIRAT
2225 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2226#else
2227 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2228#endif
2229
2230#ifdef HAVE_MKFIFOAT
2231 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2232#else
2233 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2234#endif
2235
2236#ifdef HAVE_MKNODAT
2237 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_OPENAT
2243 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2244#else
2245 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2246#endif
2247
2248#ifdef HAVE_READLINKAT
2249 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2250#else
2251 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2252#endif
2253
2254#ifdef HAVE_SYMLINKAT
2255 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2256#else
2257 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2258#endif
2259
2260#ifdef HAVE_UNLINKAT
2261 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2262#else
2263 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2264#endif
2265
2266#ifdef HAVE_FCHDIR
2267 #define PATH_HAVE_FCHDIR 1
2268#else
2269 #define PATH_HAVE_FCHDIR 0
2270#endif
2271
2272#ifdef HAVE_FCHMOD
2273 #define PATH_HAVE_FCHMOD 1
2274#else
2275 #define PATH_HAVE_FCHMOD 0
2276#endif
2277
2278#ifdef HAVE_FCHOWN
2279 #define PATH_HAVE_FCHOWN 1
2280#else
2281 #define PATH_HAVE_FCHOWN 0
2282#endif
2283
2284#ifdef HAVE_FDOPENDIR
2285 #define PATH_HAVE_FDOPENDIR 1
2286#else
2287 #define PATH_HAVE_FDOPENDIR 0
2288#endif
2289
2290#ifdef HAVE_FEXECVE
2291 #define PATH_HAVE_FEXECVE 1
2292#else
2293 #define PATH_HAVE_FEXECVE 0
2294#endif
2295
2296#ifdef HAVE_FPATHCONF
2297 #define PATH_HAVE_FPATHCONF 1
2298#else
2299 #define PATH_HAVE_FPATHCONF 0
2300#endif
2301
2302#ifdef HAVE_FSTATVFS
2303 #define PATH_HAVE_FSTATVFS 1
2304#else
2305 #define PATH_HAVE_FSTATVFS 0
2306#endif
2307
2308#ifdef HAVE_FTRUNCATE
2309 #define PATH_HAVE_FTRUNCATE 1
2310#else
2311 #define PATH_HAVE_FTRUNCATE 0
2312#endif
2313/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002314
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002315#ifdef MS_WINDOWS
2316 #undef PATH_HAVE_FTRUNCATE
2317 #define PATH_HAVE_FTRUNCATE 1
2318#endif
Larry Hastings31826802013-10-19 00:09:25 -07002319
Larry Hastings61272b72014-01-07 12:41:53 -08002320/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002321
2322class path_t_converter(CConverter):
2323
2324 type = "path_t"
2325 impl_by_reference = True
2326 parse_by_reference = True
2327
2328 converter = 'path_converter'
2329
2330 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002331 # right now path_t doesn't support default values.
2332 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002333 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002334 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002335
Larry Hastings2f936352014-08-05 14:04:04 +10002336 if self.c_default not in (None, 'Py_None'):
2337 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002338
2339 self.nullable = nullable
2340 self.allow_fd = allow_fd
2341
Larry Hastings7726ac92014-01-31 22:03:12 -08002342 def pre_render(self):
2343 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002344 if isinstance(value, str):
2345 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002346 return str(int(bool(value)))
2347
2348 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002349 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002350 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002351 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002352 strify(self.nullable),
2353 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002354 )
2355
2356 def cleanup(self):
2357 return "path_cleanup(&" + self.name + ");\n"
2358
2359
2360class dir_fd_converter(CConverter):
2361 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002362
Larry Hastings2f936352014-08-05 14:04:04 +10002363 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002364 if self.default in (unspecified, None):
2365 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002366 if isinstance(requires, str):
2367 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2368 else:
2369 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002370
Larry Hastings2f936352014-08-05 14:04:04 +10002371class fildes_converter(CConverter):
2372 type = 'int'
2373 converter = 'fildes_converter'
2374
2375class uid_t_converter(CConverter):
2376 type = "uid_t"
2377 converter = '_Py_Uid_Converter'
2378
2379class gid_t_converter(CConverter):
2380 type = "gid_t"
2381 converter = '_Py_Gid_Converter'
2382
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002383class dev_t_converter(CConverter):
2384 type = 'dev_t'
2385 converter = '_Py_Dev_Converter'
2386
2387class dev_t_return_converter(unsigned_long_return_converter):
2388 type = 'dev_t'
2389 conversion_fn = '_PyLong_FromDev'
2390 unsigned_cast = '(dev_t)'
2391
Larry Hastings2f936352014-08-05 14:04:04 +10002392class FSConverter_converter(CConverter):
2393 type = 'PyObject *'
2394 converter = 'PyUnicode_FSConverter'
2395 def converter_init(self):
2396 if self.default is not unspecified:
2397 fail("FSConverter_converter does not support default values")
2398 self.c_default = 'NULL'
2399
2400 def cleanup(self):
2401 return "Py_XDECREF(" + self.name + ");\n"
2402
2403class pid_t_converter(CConverter):
2404 type = 'pid_t'
2405 format_unit = '" _Py_PARSE_PID "'
2406
2407class idtype_t_converter(int_converter):
2408 type = 'idtype_t'
2409
2410class id_t_converter(CConverter):
2411 type = 'id_t'
2412 format_unit = '" _Py_PARSE_PID "'
2413
Benjamin Petersonca470632016-09-06 13:47:26 -07002414class intptr_t_converter(CConverter):
2415 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002416 format_unit = '" _Py_PARSE_INTPTR "'
2417
2418class Py_off_t_converter(CConverter):
2419 type = 'Py_off_t'
2420 converter = 'Py_off_t_converter'
2421
2422class Py_off_t_return_converter(long_return_converter):
2423 type = 'Py_off_t'
2424 conversion_fn = 'PyLong_FromPy_off_t'
2425
2426class path_confname_converter(CConverter):
2427 type="int"
2428 converter="conv_path_confname"
2429
2430class confstr_confname_converter(path_confname_converter):
2431 converter='conv_confstr_confname'
2432
2433class sysconf_confname_converter(path_confname_converter):
2434 converter="conv_sysconf_confname"
2435
2436class sched_param_converter(CConverter):
2437 type = 'struct sched_param'
2438 converter = 'convert_sched_param'
2439 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002440
Larry Hastings61272b72014-01-07 12:41:53 -08002441[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002442/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002443
Larry Hastings61272b72014-01-07 12:41:53 -08002444/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002445
Larry Hastings2a727912014-01-16 11:32:01 -08002446os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002447
2448 path : path_t(allow_fd=True)
BNMetrics08026b12018-11-02 17:56:25 +00002449 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002450 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002451
2452 *
2453
Larry Hastings2f936352014-08-05 14:04:04 +10002454 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002455 If not None, it should be a file descriptor open to a directory,
2456 and path should be a relative string; path will then be relative to
2457 that directory.
2458
2459 follow_symlinks: bool = True
2460 If False, and the last element of the path is a symbolic link,
2461 stat will examine the symbolic link itself instead of the file
2462 the link points to.
2463
2464Perform a stat system call on the given path.
2465
2466dir_fd and follow_symlinks may not be implemented
2467 on your platform. If they are unavailable, using them will raise a
2468 NotImplementedError.
2469
2470It's an error to use dir_fd or follow_symlinks when specifying path as
2471 an open file descriptor.
2472
Larry Hastings61272b72014-01-07 12:41:53 -08002473[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002474
Larry Hastings31826802013-10-19 00:09:25 -07002475static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002476os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002477/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002478{
2479 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2480}
2481
Larry Hastings2f936352014-08-05 14:04:04 +10002482
2483/*[clinic input]
2484os.lstat
2485
2486 path : path_t
2487
2488 *
2489
2490 dir_fd : dir_fd(requires='fstatat') = None
2491
2492Perform a stat system call on the given path, without following symbolic links.
2493
2494Like stat(), but do not follow symbolic links.
2495Equivalent to stat(path, follow_symlinks=False).
2496[clinic start generated code]*/
2497
Larry Hastings2f936352014-08-05 14:04:04 +10002498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002499os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2500/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002501{
2502 int follow_symlinks = 0;
2503 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2504}
Larry Hastings31826802013-10-19 00:09:25 -07002505
Larry Hastings2f936352014-08-05 14:04:04 +10002506
Larry Hastings61272b72014-01-07 12:41:53 -08002507/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002508os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002509
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002510 path: path_t
BNMetrics08026b12018-11-02 17:56:25 +00002511 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002512
2513 mode: int
2514 Operating-system mode bitfield. Can be F_OK to test existence,
2515 or the inclusive-OR of R_OK, W_OK, and X_OK.
2516
2517 *
2518
Larry Hastings2f936352014-08-05 14:04:04 +10002519 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002520 If not None, it should be a file descriptor open to a directory,
2521 and path should be relative; path will then be relative to that
2522 directory.
2523
2524 effective_ids: bool = False
2525 If True, access will use the effective uid/gid instead of
2526 the real uid/gid.
2527
2528 follow_symlinks: bool = True
2529 If False, and the last element of the path is a symbolic link,
2530 access will examine the symbolic link itself instead of the file
2531 the link points to.
2532
2533Use the real uid/gid to test for access to a path.
2534
2535{parameters}
2536dir_fd, effective_ids, and follow_symlinks may not be implemented
2537 on your platform. If they are unavailable, using them will raise a
2538 NotImplementedError.
2539
2540Note that most operations will use the effective uid/gid, therefore this
2541 routine can be used in a suid/sgid environment to test if the invoking user
2542 has the specified access to the path.
2543
Larry Hastings61272b72014-01-07 12:41:53 -08002544[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002545
Larry Hastings2f936352014-08-05 14:04:04 +10002546static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002547os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002548 int effective_ids, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002549/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002550{
Larry Hastings2f936352014-08-05 14:04:04 +10002551 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002552
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002553#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002554 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002555#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002556 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002557#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002558
Larry Hastings9cf065c2012-06-22 16:30:09 -07002559#ifndef HAVE_FACCESSAT
2560 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002561 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002562
2563 if (effective_ids) {
2564 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002565 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002566 }
2567#endif
2568
2569#ifdef MS_WINDOWS
2570 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002571 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572 Py_END_ALLOW_THREADS
2573
2574 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002575 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576 * * we didn't get a -1, and
2577 * * write access wasn't requested,
2578 * * or the file isn't read-only,
2579 * * or it's a directory.
2580 * (Directories cannot be read-only on Windows.)
2581 */
Larry Hastings2f936352014-08-05 14:04:04 +10002582 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002583 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002584 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002585 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002586#else
2587
2588 Py_BEGIN_ALLOW_THREADS
2589#ifdef HAVE_FACCESSAT
2590 if ((dir_fd != DEFAULT_DIR_FD) ||
2591 effective_ids ||
2592 !follow_symlinks) {
2593 int flags = 0;
2594 if (!follow_symlinks)
2595 flags |= AT_SYMLINK_NOFOLLOW;
2596 if (effective_ids)
2597 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002598 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002599 }
2600 else
2601#endif
Larry Hastings31826802013-10-19 00:09:25 -07002602 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002604 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605#endif
2606
Larry Hastings9cf065c2012-06-22 16:30:09 -07002607 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002608}
2609
Guido van Rossumd371ff11999-01-25 16:12:23 +00002610#ifndef F_OK
2611#define F_OK 0
2612#endif
2613#ifndef R_OK
2614#define R_OK 4
2615#endif
2616#ifndef W_OK
2617#define W_OK 2
2618#endif
2619#ifndef X_OK
2620#define X_OK 1
2621#endif
2622
Larry Hastings31826802013-10-19 00:09:25 -07002623
Guido van Rossumd371ff11999-01-25 16:12:23 +00002624#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002625/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002626os.ttyname -> DecodeFSDefault
2627
2628 fd: int
2629 Integer file descriptor handle.
2630
2631 /
2632
2633Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002634[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002635
Larry Hastings31826802013-10-19 00:09:25 -07002636static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002637os_ttyname_impl(PyObject *module, int fd)
2638/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002639{
2640 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002641
Larry Hastings31826802013-10-19 00:09:25 -07002642 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002643 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002644 posix_error();
2645 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002646}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002647#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002648
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002649#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002650/*[clinic input]
2651os.ctermid
2652
2653Return the name of the controlling terminal for this process.
2654[clinic start generated code]*/
2655
Larry Hastings2f936352014-08-05 14:04:04 +10002656static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002657os_ctermid_impl(PyObject *module)
2658/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002659{
Victor Stinner8c62be82010-05-06 00:08:46 +00002660 char *ret;
2661 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002662
Greg Wardb48bc172000-03-01 21:51:56 +00002663#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002664 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002665#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002666 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002667#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 if (ret == NULL)
2669 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002670 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002671}
Larry Hastings2f936352014-08-05 14:04:04 +10002672#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002673
Larry Hastings2f936352014-08-05 14:04:04 +10002674
2675/*[clinic input]
2676os.chdir
2677
2678 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2679
2680Change the current working directory to the specified path.
2681
2682path may always be specified as a string.
2683On some platforms, path may also be specified as an open file descriptor.
2684 If this functionality is unavailable, using it raises an exception.
2685[clinic start generated code]*/
2686
Larry Hastings2f936352014-08-05 14:04:04 +10002687static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002688os_chdir_impl(PyObject *module, path_t *path)
2689/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002690{
2691 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002692
2693 Py_BEGIN_ALLOW_THREADS
2694#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002695 /* on unix, success = 0, on windows, success = !0 */
2696 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697#else
2698#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002699 if (path->fd != -1)
2700 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002701 else
2702#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002703 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002704#endif
2705 Py_END_ALLOW_THREADS
2706
2707 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002708 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002709 }
2710
Larry Hastings2f936352014-08-05 14:04:04 +10002711 Py_RETURN_NONE;
2712}
2713
2714
2715#ifdef HAVE_FCHDIR
2716/*[clinic input]
2717os.fchdir
2718
2719 fd: fildes
2720
2721Change to the directory of the given file descriptor.
2722
2723fd must be opened on a directory, not a file.
2724Equivalent to os.chdir(fd).
2725
2726[clinic start generated code]*/
2727
Fred Drake4d1e64b2002-04-15 19:40:07 +00002728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002729os_fchdir_impl(PyObject *module, int fd)
2730/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002731{
Larry Hastings2f936352014-08-05 14:04:04 +10002732 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002733}
2734#endif /* HAVE_FCHDIR */
2735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002736
Larry Hastings2f936352014-08-05 14:04:04 +10002737/*[clinic input]
2738os.chmod
2739
2740 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetrics08026b12018-11-02 17:56:25 +00002741 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002742 On some platforms, path may also be specified as an open file descriptor.
2743 If this functionality is unavailable, using it raises an exception.
2744
2745 mode: int
2746 Operating-system mode bitfield.
2747
2748 *
2749
2750 dir_fd : dir_fd(requires='fchmodat') = None
2751 If not None, it should be a file descriptor open to a directory,
2752 and path should be relative; path will then be relative to that
2753 directory.
2754
2755 follow_symlinks: bool = True
2756 If False, and the last element of the path is a symbolic link,
2757 chmod will modify the symbolic link itself instead of the file
2758 the link points to.
2759
2760Change the access permissions of a file.
2761
2762It is an error to use dir_fd or follow_symlinks when specifying path as
2763 an open file descriptor.
2764dir_fd and follow_symlinks may not be implemented on your platform.
2765 If they are unavailable, using them will raise a NotImplementedError.
2766
2767[clinic start generated code]*/
2768
Larry Hastings2f936352014-08-05 14:04:04 +10002769static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002770os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002771 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002772/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002773{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002774 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002775
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002776#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002778#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002779
Larry Hastings9cf065c2012-06-22 16:30:09 -07002780#ifdef HAVE_FCHMODAT
2781 int fchmodat_nofollow_unsupported = 0;
2782#endif
2783
Larry Hastings9cf065c2012-06-22 16:30:09 -07002784#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2785 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002786 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002787#endif
2788
2789#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002790 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002791 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002792 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793 result = 0;
2794 else {
2795 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002796 attr &= ~FILE_ATTRIBUTE_READONLY;
2797 else
2798 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002799 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800 }
2801 Py_END_ALLOW_THREADS
2802
2803 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002804 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002805 }
2806#else /* MS_WINDOWS */
2807 Py_BEGIN_ALLOW_THREADS
2808#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002809 if (path->fd != -1)
2810 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811 else
2812#endif
2813#ifdef HAVE_LCHMOD
2814 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002815 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816 else
2817#endif
2818#ifdef HAVE_FCHMODAT
2819 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2820 /*
2821 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2822 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002823 * and then says it isn't implemented yet.
2824 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825 *
2826 * Once it is supported, os.chmod will automatically
2827 * support dir_fd and follow_symlinks=False. (Hopefully.)
2828 * Until then, we need to be careful what exception we raise.
2829 */
Larry Hastings2f936352014-08-05 14:04:04 +10002830 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2832 /*
2833 * But wait! We can't throw the exception without allowing threads,
2834 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2835 */
2836 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002837 result &&
2838 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2839 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002840 }
2841 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002842#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002843 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844 Py_END_ALLOW_THREADS
2845
2846 if (result) {
2847#ifdef HAVE_FCHMODAT
2848 if (fchmodat_nofollow_unsupported) {
2849 if (dir_fd != DEFAULT_DIR_FD)
2850 dir_fd_and_follow_symlinks_invalid("chmod",
2851 dir_fd, follow_symlinks);
2852 else
2853 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002854 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 }
2856 else
2857#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002858 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859 }
2860#endif
2861
Larry Hastings2f936352014-08-05 14:04:04 +10002862 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002863}
2864
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865
Christian Heimes4e30a842007-11-30 22:12:06 +00002866#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002867/*[clinic input]
2868os.fchmod
2869
2870 fd: int
2871 mode: int
2872
2873Change the access permissions of the file given by file descriptor fd.
2874
2875Equivalent to os.chmod(fd, mode).
2876[clinic start generated code]*/
2877
Larry Hastings2f936352014-08-05 14:04:04 +10002878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002879os_fchmod_impl(PyObject *module, int fd, int mode)
2880/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002881{
2882 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002883 int async_err = 0;
2884
2885 do {
2886 Py_BEGIN_ALLOW_THREADS
2887 res = fchmod(fd, mode);
2888 Py_END_ALLOW_THREADS
2889 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2890 if (res != 0)
2891 return (!async_err) ? posix_error() : NULL;
2892
Victor Stinner8c62be82010-05-06 00:08:46 +00002893 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002894}
2895#endif /* HAVE_FCHMOD */
2896
Larry Hastings2f936352014-08-05 14:04:04 +10002897
Christian Heimes4e30a842007-11-30 22:12:06 +00002898#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002899/*[clinic input]
2900os.lchmod
2901
2902 path: path_t
2903 mode: int
2904
2905Change the access permissions of a file, without following symbolic links.
2906
2907If path is a symlink, this affects the link itself rather than the target.
2908Equivalent to chmod(path, mode, follow_symlinks=False)."
2909[clinic start generated code]*/
2910
Larry Hastings2f936352014-08-05 14:04:04 +10002911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002912os_lchmod_impl(PyObject *module, path_t *path, int mode)
2913/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002914{
Victor Stinner8c62be82010-05-06 00:08:46 +00002915 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002917 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002919 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002920 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002921 return NULL;
2922 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002923 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002924}
2925#endif /* HAVE_LCHMOD */
2926
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002927
Thomas Wouterscf297e42007-02-23 15:07:44 +00002928#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002929/*[clinic input]
2930os.chflags
2931
2932 path: path_t
2933 flags: unsigned_long(bitwise=True)
2934 follow_symlinks: bool=True
2935
2936Set file flags.
2937
2938If follow_symlinks is False, and the last element of the path is a symbolic
2939 link, chflags will change flags on the symbolic link itself instead of the
2940 file the link points to.
2941follow_symlinks may not be implemented on your platform. If it is
2942unavailable, using it will raise a NotImplementedError.
2943
2944[clinic start generated code]*/
2945
Larry Hastings2f936352014-08-05 14:04:04 +10002946static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002947os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002948 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002949/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002950{
2951 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002952
2953#ifndef HAVE_LCHFLAGS
2954 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002955 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002956#endif
2957
Victor Stinner8c62be82010-05-06 00:08:46 +00002958 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002959#ifdef HAVE_LCHFLAGS
2960 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002961 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962 else
2963#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002964 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002965 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002966
Larry Hastings2f936352014-08-05 14:04:04 +10002967 if (result)
2968 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002969
Larry Hastings2f936352014-08-05 14:04:04 +10002970 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002971}
2972#endif /* HAVE_CHFLAGS */
2973
Larry Hastings2f936352014-08-05 14:04:04 +10002974
Thomas Wouterscf297e42007-02-23 15:07:44 +00002975#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002976/*[clinic input]
2977os.lchflags
2978
2979 path: path_t
2980 flags: unsigned_long(bitwise=True)
2981
2982Set file flags.
2983
2984This function will not follow symbolic links.
2985Equivalent to chflags(path, flags, follow_symlinks=False).
2986[clinic start generated code]*/
2987
Larry Hastings2f936352014-08-05 14:04:04 +10002988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002989os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2990/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002991{
Victor Stinner8c62be82010-05-06 00:08:46 +00002992 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002993 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002994 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002995 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002996 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002997 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002998 }
Victor Stinner292c8352012-10-30 02:17:38 +01002999 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003000}
3001#endif /* HAVE_LCHFLAGS */
3002
Larry Hastings2f936352014-08-05 14:04:04 +10003003
Martin v. Löwis244edc82001-10-04 22:44:26 +00003004#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003005/*[clinic input]
3006os.chroot
3007 path: path_t
3008
3009Change root directory to path.
3010
3011[clinic start generated code]*/
3012
Larry Hastings2f936352014-08-05 14:04:04 +10003013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003014os_chroot_impl(PyObject *module, path_t *path)
3015/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003016{
3017 int res;
3018 Py_BEGIN_ALLOW_THREADS
3019 res = chroot(path->narrow);
3020 Py_END_ALLOW_THREADS
3021 if (res < 0)
3022 return path_error(path);
3023 Py_RETURN_NONE;
3024}
3025#endif /* HAVE_CHROOT */
3026
Martin v. Löwis244edc82001-10-04 22:44:26 +00003027
Guido van Rossum21142a01999-01-08 21:05:37 +00003028#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003029/*[clinic input]
3030os.fsync
3031
3032 fd: fildes
3033
3034Force write of fd to disk.
3035[clinic start generated code]*/
3036
Larry Hastings2f936352014-08-05 14:04:04 +10003037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003038os_fsync_impl(PyObject *module, int fd)
3039/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003040{
3041 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003042}
3043#endif /* HAVE_FSYNC */
3044
Larry Hastings2f936352014-08-05 14:04:04 +10003045
Ross Lagerwall7807c352011-03-17 20:20:30 +02003046#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003047/*[clinic input]
3048os.sync
3049
3050Force write of everything to disk.
3051[clinic start generated code]*/
3052
Larry Hastings2f936352014-08-05 14:04:04 +10003053static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003054os_sync_impl(PyObject *module)
3055/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003056{
3057 Py_BEGIN_ALLOW_THREADS
3058 sync();
3059 Py_END_ALLOW_THREADS
3060 Py_RETURN_NONE;
3061}
Larry Hastings2f936352014-08-05 14:04:04 +10003062#endif /* HAVE_SYNC */
3063
Ross Lagerwall7807c352011-03-17 20:20:30 +02003064
Guido van Rossum21142a01999-01-08 21:05:37 +00003065#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003066#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003067extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3068#endif
3069
Larry Hastings2f936352014-08-05 14:04:04 +10003070/*[clinic input]
3071os.fdatasync
3072
3073 fd: fildes
3074
3075Force write of fd to disk without forcing update of metadata.
3076[clinic start generated code]*/
3077
Larry Hastings2f936352014-08-05 14:04:04 +10003078static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003079os_fdatasync_impl(PyObject *module, int fd)
3080/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003081{
3082 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003083}
3084#endif /* HAVE_FDATASYNC */
3085
3086
Fredrik Lundh10723342000-07-10 16:38:09 +00003087#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003088/*[clinic input]
3089os.chown
3090
3091 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetrics08026b12018-11-02 17:56:25 +00003092 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003093
3094 uid: uid_t
3095
3096 gid: gid_t
3097
3098 *
3099
3100 dir_fd : dir_fd(requires='fchownat') = None
3101 If not None, it should be a file descriptor open to a directory,
3102 and path should be relative; path will then be relative to that
3103 directory.
3104
3105 follow_symlinks: bool = True
3106 If False, and the last element of the path is a symbolic link,
3107 stat will examine the symbolic link itself instead of the file
3108 the link points to.
3109
3110Change the owner and group id of path to the numeric uid and gid.\
3111
3112path may always be specified as a string.
3113On some platforms, path may also be specified as an open file descriptor.
3114 If this functionality is unavailable, using it raises an exception.
3115If dir_fd is not None, it should be a file descriptor open to a directory,
3116 and path should be relative; path will then be relative to that directory.
3117If follow_symlinks is False, and the last element of the path is a symbolic
3118 link, chown will modify the symbolic link itself instead of the file the
3119 link points to.
3120It is an error to use dir_fd or follow_symlinks when specifying path as
3121 an open file descriptor.
3122dir_fd and follow_symlinks may not be implemented on your platform.
3123 If they are unavailable, using them will raise a NotImplementedError.
3124
3125[clinic start generated code]*/
3126
Larry Hastings2f936352014-08-05 14:04:04 +10003127static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003128os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003129 int dir_fd, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00003130/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003131{
3132 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003133
3134#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3135 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003136 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003137#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003138 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3139 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3140 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003141
3142#ifdef __APPLE__
3143 /*
3144 * This is for Mac OS X 10.3, which doesn't have lchown.
3145 * (But we still have an lchown symbol because of weak-linking.)
3146 * It doesn't have fchownat either. So there's no possibility
3147 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003148 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003149 if ((!follow_symlinks) && (lchown == NULL)) {
3150 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003151 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003152 }
3153#endif
3154
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003157 if (path->fd != -1)
3158 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003159 else
3160#endif
3161#ifdef HAVE_LCHOWN
3162 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003163 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003164 else
3165#endif
3166#ifdef HAVE_FCHOWNAT
3167 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003168 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003169 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3170 else
3171#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003172 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174
Larry Hastings2f936352014-08-05 14:04:04 +10003175 if (result)
3176 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003177
Larry Hastings2f936352014-08-05 14:04:04 +10003178 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003179}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003180#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003181
Larry Hastings2f936352014-08-05 14:04:04 +10003182
Christian Heimes4e30a842007-11-30 22:12:06 +00003183#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003184/*[clinic input]
3185os.fchown
3186
3187 fd: int
3188 uid: uid_t
3189 gid: gid_t
3190
3191Change the owner and group id of the file specified by file descriptor.
3192
3193Equivalent to os.chown(fd, uid, gid).
3194
3195[clinic start generated code]*/
3196
Larry Hastings2f936352014-08-05 14:04:04 +10003197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003198os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3199/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003200{
Victor Stinner8c62be82010-05-06 00:08:46 +00003201 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003202 int async_err = 0;
3203
3204 do {
3205 Py_BEGIN_ALLOW_THREADS
3206 res = fchown(fd, uid, gid);
3207 Py_END_ALLOW_THREADS
3208 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3209 if (res != 0)
3210 return (!async_err) ? posix_error() : NULL;
3211
Victor Stinner8c62be82010-05-06 00:08:46 +00003212 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003213}
3214#endif /* HAVE_FCHOWN */
3215
Larry Hastings2f936352014-08-05 14:04:04 +10003216
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003217#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003218/*[clinic input]
3219os.lchown
3220
3221 path : path_t
3222 uid: uid_t
3223 gid: gid_t
3224
3225Change the owner and group id of path to the numeric uid and gid.
3226
3227This function will not follow symbolic links.
3228Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3229[clinic start generated code]*/
3230
Larry Hastings2f936352014-08-05 14:04:04 +10003231static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003232os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3233/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003234{
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003237 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003238 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003239 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003240 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003241 }
Larry Hastings2f936352014-08-05 14:04:04 +10003242 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003243}
3244#endif /* HAVE_LCHOWN */
3245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003246
Barry Warsaw53699e91996-12-10 23:23:01 +00003247static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003248posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003249{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003250 char *buf, *tmpbuf;
3251 char *cwd;
3252 const size_t chunk = 1024;
3253 size_t buflen = 0;
3254 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003255
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003256#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003258 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003259 wchar_t *wbuf2 = wbuf;
3260 PyObject *resobj;
3261 DWORD len;
3262 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003263 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003264 /* If the buffer is large enough, len does not include the
3265 terminating \0. If the buffer is too small, len includes
3266 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003267 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003268 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003269 if (wbuf2)
3270 len = GetCurrentDirectoryW(len, wbuf2);
3271 }
3272 Py_END_ALLOW_THREADS
3273 if (!wbuf2) {
3274 PyErr_NoMemory();
3275 return NULL;
3276 }
3277 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003278 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003279 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003280 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003281 }
3282 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003283 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003284 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003285 return resobj;
3286 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003287
3288 if (win32_warn_bytes_api())
3289 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003290#endif
3291
Victor Stinner4403d7d2015-04-25 00:16:10 +02003292 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003293 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003294 do {
3295 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003296#ifdef MS_WINDOWS
3297 if (buflen > INT_MAX) {
3298 PyErr_NoMemory();
3299 break;
3300 }
3301#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003302 tmpbuf = PyMem_RawRealloc(buf, buflen);
3303 if (tmpbuf == NULL)
3304 break;
3305
3306 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003307#ifdef MS_WINDOWS
3308 cwd = getcwd(buf, (int)buflen);
3309#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003310 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003311#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003312 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003313 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003314
3315 if (cwd == NULL) {
3316 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003317 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003318 }
3319
Victor Stinner8c62be82010-05-06 00:08:46 +00003320 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003321 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3322 else
3323 obj = PyUnicode_DecodeFSDefault(buf);
3324 PyMem_RawFree(buf);
3325
3326 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003327}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003328
Larry Hastings2f936352014-08-05 14:04:04 +10003329
3330/*[clinic input]
3331os.getcwd
3332
3333Return a unicode string representing the current working directory.
3334[clinic start generated code]*/
3335
Larry Hastings2f936352014-08-05 14:04:04 +10003336static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003337os_getcwd_impl(PyObject *module)
3338/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003339{
3340 return posix_getcwd(0);
3341}
3342
Larry Hastings2f936352014-08-05 14:04:04 +10003343
3344/*[clinic input]
3345os.getcwdb
3346
3347Return a bytes string representing the current working directory.
3348[clinic start generated code]*/
3349
Larry Hastings2f936352014-08-05 14:04:04 +10003350static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003351os_getcwdb_impl(PyObject *module)
3352/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003353{
3354 return posix_getcwd(1);
3355}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003356
Larry Hastings2f936352014-08-05 14:04:04 +10003357
Larry Hastings9cf065c2012-06-22 16:30:09 -07003358#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3359#define HAVE_LINK 1
3360#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003361
Guido van Rossumb6775db1994-08-01 11:34:53 +00003362#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003363/*[clinic input]
3364
3365os.link
3366
3367 src : path_t
3368 dst : path_t
3369 *
3370 src_dir_fd : dir_fd = None
3371 dst_dir_fd : dir_fd = None
3372 follow_symlinks: bool = True
3373
3374Create a hard link to a file.
3375
3376If either src_dir_fd or dst_dir_fd is not None, it should be a file
3377 descriptor open to a directory, and the respective path string (src or dst)
3378 should be relative; the path will then be relative to that directory.
3379If follow_symlinks is False, and the last element of src is a symbolic
3380 link, link will create a link to the symbolic link itself instead of the
3381 file the link points to.
3382src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3383 platform. If they are unavailable, using them will raise a
3384 NotImplementedError.
3385[clinic start generated code]*/
3386
Larry Hastings2f936352014-08-05 14:04:04 +10003387static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003388os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003389 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003390/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003391{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003393 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003394#else
3395 int result;
3396#endif
3397
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398#ifndef HAVE_LINKAT
3399 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3400 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003401 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003402 }
3403#endif
3404
Steve Dowercc16be82016-09-08 10:35:16 -07003405#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003406 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003407 PyErr_SetString(PyExc_NotImplementedError,
3408 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003409 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003410 }
Steve Dowercc16be82016-09-08 10:35:16 -07003411#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003412
Brian Curtin1b9df392010-11-24 20:24:31 +00003413#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003414 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003415 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003417
Larry Hastings2f936352014-08-05 14:04:04 +10003418 if (!result)
3419 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420#else
3421 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003422#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3424 (dst_dir_fd != DEFAULT_DIR_FD) ||
3425 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003426 result = linkat(src_dir_fd, src->narrow,
3427 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3429 else
Steve Dowercc16be82016-09-08 10:35:16 -07003430#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003431 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003433
Larry Hastings2f936352014-08-05 14:04:04 +10003434 if (result)
3435 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003436#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437
Larry Hastings2f936352014-08-05 14:04:04 +10003438 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003439}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440#endif
3441
Brian Curtin1b9df392010-11-24 20:24:31 +00003442
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003443#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003444static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003445_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003446{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447 PyObject *v;
3448 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3449 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003450 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003451 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003452 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454
Steve Dowercc16be82016-09-08 10:35:16 -07003455 WIN32_FIND_DATAW wFileData;
3456 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003457
Steve Dowercc16be82016-09-08 10:35:16 -07003458 if (!path->wide) { /* Default arg: "." */
3459 po_wchars = L".";
3460 len = 1;
3461 } else {
3462 po_wchars = path->wide;
3463 len = wcslen(path->wide);
3464 }
3465 /* The +5 is so we can append "\\*.*\0" */
3466 wnamebuf = PyMem_New(wchar_t, len + 5);
3467 if (!wnamebuf) {
3468 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 }
Steve Dowercc16be82016-09-08 10:35:16 -07003471 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003472 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003473 wchar_t wch = wnamebuf[len-1];
3474 if (wch != SEP && wch != ALTSEP && wch != L':')
3475 wnamebuf[len++] = SEP;
3476 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003477 }
Steve Dowercc16be82016-09-08 10:35:16 -07003478 if ((list = PyList_New(0)) == NULL) {
3479 goto exit;
3480 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003481 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003482 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003483 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 if (hFindFile == INVALID_HANDLE_VALUE) {
3485 int error = GetLastError();
3486 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 goto exit;
3488 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003489 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 }
3492 do {
3493 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003494 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3495 wcscmp(wFileData.cFileName, L"..") != 0) {
3496 v = PyUnicode_FromWideChar(wFileData.cFileName,
3497 wcslen(wFileData.cFileName));
3498 if (path->narrow && v) {
3499 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3500 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003501 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 Py_DECREF(list);
3503 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 break;
3505 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 Py_DECREF(list);
3509 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003510 break;
3511 }
3512 Py_DECREF(v);
3513 }
3514 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003515 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 Py_END_ALLOW_THREADS
3517 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3518 it got to the end of the directory. */
3519 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003521 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003522 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 }
3524 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003525
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526exit:
3527 if (hFindFile != INVALID_HANDLE_VALUE) {
3528 if (FindClose(hFindFile) == FALSE) {
3529 if (list != NULL) {
3530 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003531 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 }
3533 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003535 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003536
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003538} /* end of _listdir_windows_no_opendir */
3539
3540#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3541
3542static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003543_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003544{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003545 PyObject *v;
3546 DIR *dirp = NULL;
3547 struct dirent *ep;
3548 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003549#ifdef HAVE_FDOPENDIR
3550 int fd = -1;
3551#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003552
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003555 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003557 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003558 if (fd == -1)
3559 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560
Larry Hastingsfdaea062012-06-25 04:42:23 -07003561 return_str = 1;
3562
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 Py_BEGIN_ALLOW_THREADS
3564 dirp = fdopendir(fd);
3565 Py_END_ALLOW_THREADS
3566 }
3567 else
3568#endif
3569 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003570 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003571 if (path->narrow) {
3572 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003573 /* only return bytes if they specified a bytes-like object */
3574 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003575 }
3576 else {
3577 name = ".";
3578 return_str = 1;
3579 }
3580
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 Py_BEGIN_ALLOW_THREADS
3582 dirp = opendir(name);
3583 Py_END_ALLOW_THREADS
3584 }
3585
3586 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003587 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003588#ifdef HAVE_FDOPENDIR
3589 if (fd != -1) {
3590 Py_BEGIN_ALLOW_THREADS
3591 close(fd);
3592 Py_END_ALLOW_THREADS
3593 }
3594#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003595 goto exit;
3596 }
3597 if ((list = PyList_New(0)) == NULL) {
3598 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 }
3600 for (;;) {
3601 errno = 0;
3602 Py_BEGIN_ALLOW_THREADS
3603 ep = readdir(dirp);
3604 Py_END_ALLOW_THREADS
3605 if (ep == NULL) {
3606 if (errno == 0) {
3607 break;
3608 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003610 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 }
3613 }
3614 if (ep->d_name[0] == '.' &&
3615 (NAMLEN(ep) == 1 ||
3616 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3617 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003618 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003619 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3620 else
3621 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003622 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 break;
3625 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003629 break;
3630 }
3631 Py_DECREF(v);
3632 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003633
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634exit:
3635 if (dirp != NULL) {
3636 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003637#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003638 if (fd > -1)
3639 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003640#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003641 closedir(dirp);
3642 Py_END_ALLOW_THREADS
3643 }
3644
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003646} /* end of _posix_listdir */
3647#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003648
Larry Hastings2f936352014-08-05 14:04:04 +10003649
3650/*[clinic input]
3651os.listdir
3652
3653 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3654
3655Return a list containing the names of the files in the directory.
3656
BNMetrics08026b12018-11-02 17:56:25 +00003657path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003658 the filenames returned will also be bytes; in all other circumstances
3659 the filenames returned will be str.
3660If path is None, uses the path='.'.
3661On some platforms, path may also be specified as an open file descriptor;\
3662 the file descriptor must refer to a directory.
3663 If this functionality is unavailable, using it raises NotImplementedError.
3664
3665The list is in arbitrary order. It does not include the special
3666entries '.' and '..' even if they are present in the directory.
3667
3668
3669[clinic start generated code]*/
3670
Larry Hastings2f936352014-08-05 14:04:04 +10003671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003672os_listdir_impl(PyObject *module, path_t *path)
BNMetrics08026b12018-11-02 17:56:25 +00003673/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003674{
3675#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3676 return _listdir_windows_no_opendir(path, NULL);
3677#else
3678 return _posix_listdir(path, NULL);
3679#endif
3680}
3681
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003682#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003683/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003684/*[clinic input]
3685os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003686
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003687 path: path_t
3688 /
3689
3690[clinic start generated code]*/
3691
3692static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003693os__getfullpathname_impl(PyObject *module, path_t *path)
3694/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003695{
Steve Dowercc16be82016-09-08 10:35:16 -07003696 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3697 wchar_t *wtemp;
3698 DWORD result;
3699 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003700
Steve Dowercc16be82016-09-08 10:35:16 -07003701 result = GetFullPathNameW(path->wide,
3702 Py_ARRAY_LENGTH(woutbuf),
3703 woutbuf, &wtemp);
3704 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3705 woutbufp = PyMem_New(wchar_t, result);
3706 if (!woutbufp)
3707 return PyErr_NoMemory();
3708 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 }
Steve Dowercc16be82016-09-08 10:35:16 -07003710 if (result) {
3711 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3712 if (path->narrow)
3713 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3714 } else
3715 v = win32_error_object("GetFullPathNameW", path->object);
3716 if (woutbufp != woutbuf)
3717 PyMem_Free(woutbufp);
3718 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003719}
Brian Curtind40e6f72010-07-08 21:39:08 +00003720
Brian Curtind25aef52011-06-13 15:16:04 -05003721
Larry Hastings2f936352014-08-05 14:04:04 +10003722/*[clinic input]
3723os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003724
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003725 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003726 /
3727
3728A helper function for samepath on windows.
3729[clinic start generated code]*/
3730
Larry Hastings2f936352014-08-05 14:04:04 +10003731static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003732os__getfinalpathname_impl(PyObject *module, path_t *path)
3733/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003734{
3735 HANDLE hFile;
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003736 wchar_t buf[MAXPATHLEN], *target_path = buf;
3737 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003738 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003739 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003740
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003741 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003742 hFile = CreateFileW(
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003743 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003744 0, /* desired access */
3745 0, /* share mode */
3746 NULL, /* security attributes */
3747 OPEN_EXISTING,
3748 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3749 FILE_FLAG_BACKUP_SEMANTICS,
3750 NULL);
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003751 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003752
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003753 if (hFile == INVALID_HANDLE_VALUE) {
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003754 return win32_error_object("CreateFileW", path->object);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003755 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003756
3757 /* We have a good handle to the target, use it to determine the
3758 target path name. */
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003759 while (1) {
3760 Py_BEGIN_ALLOW_THREADS
3761 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3762 buf_size, VOLUME_NAME_DOS);
3763 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003764
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003765 if (!result_length) {
3766 result = win32_error_object("GetFinalPathNameByHandleW",
3767 path->object);
3768 goto cleanup;
3769 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003770
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003771 if (result_length < buf_size) {
3772 break;
3773 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003774
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003775 wchar_t *tmp;
3776 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3777 result_length * sizeof(*tmp));
3778 if (!tmp) {
3779 result = PyErr_NoMemory();
3780 goto cleanup;
3781 }
3782
3783 buf_size = result_length;
3784 target_path = tmp;
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003785 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003786
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003787 result = PyUnicode_FromWideChar(target_path, result_length);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003788 if (path->narrow)
3789 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003790
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003791cleanup:
3792 if (target_path != buf) {
3793 PyMem_Free(target_path);
3794 }
3795 CloseHandle(hFile);
3796 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003797}
Brian Curtin62857742010-09-06 17:07:27 +00003798
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003799/*[clinic input]
3800os._isdir
3801
3802 path: path_t
3803 /
3804
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003805Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003806[clinic start generated code]*/
3807
Brian Curtin9c669cc2011-06-08 18:17:18 -05003808static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003809os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003810/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003811{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003812 DWORD attributes;
3813
Steve Dowerb22a6772016-07-17 20:49:38 -07003814 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003815 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003816 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003817
Brian Curtin9c669cc2011-06-08 18:17:18 -05003818 if (attributes == INVALID_FILE_ATTRIBUTES)
3819 Py_RETURN_FALSE;
3820
Brian Curtin9c669cc2011-06-08 18:17:18 -05003821 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3822 Py_RETURN_TRUE;
3823 else
3824 Py_RETURN_FALSE;
3825}
Tim Golden6b528062013-08-01 12:44:00 +01003826
Tim Golden6b528062013-08-01 12:44:00 +01003827
Larry Hastings2f936352014-08-05 14:04:04 +10003828/*[clinic input]
3829os._getvolumepathname
3830
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003831 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003832
3833A helper function for ismount on Win32.
3834[clinic start generated code]*/
3835
Larry Hastings2f936352014-08-05 14:04:04 +10003836static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003837os__getvolumepathname_impl(PyObject *module, path_t *path)
3838/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003839{
3840 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003841 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003842 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003843 BOOL ret;
3844
Tim Golden6b528062013-08-01 12:44:00 +01003845 /* Volume path should be shorter than entire path */
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003846 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003847
Victor Stinner850a18e2017-10-24 16:53:32 -07003848 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003849 PyErr_SetString(PyExc_OverflowError, "path too long");
3850 return NULL;
3851 }
3852
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003853 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003854 if (mountpath == NULL)
3855 return PyErr_NoMemory();
3856
3857 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003858 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003859 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003860 Py_END_ALLOW_THREADS
3861
3862 if (!ret) {
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003863 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003864 goto exit;
3865 }
3866 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003867 if (path->narrow)
3868 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003869
3870exit:
3871 PyMem_Free(mountpath);
3872 return result;
3873}
Tim Golden6b528062013-08-01 12:44:00 +01003874
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003875#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003876
Larry Hastings2f936352014-08-05 14:04:04 +10003877
3878/*[clinic input]
3879os.mkdir
3880
3881 path : path_t
3882
3883 mode: int = 0o777
3884
3885 *
3886
3887 dir_fd : dir_fd(requires='mkdirat') = None
3888
3889# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3890
3891Create a directory.
3892
3893If dir_fd is not None, it should be a file descriptor open to a directory,
3894 and path should be relative; path will then be relative to that directory.
3895dir_fd may not be implemented on your platform.
3896 If it is unavailable, using it will raise a NotImplementedError.
3897
3898The mode argument is ignored on Windows.
3899[clinic start generated code]*/
3900
Larry Hastings2f936352014-08-05 14:04:04 +10003901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003902os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3903/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003904{
3905 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003906
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003907#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003908 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003909 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003910 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003911
Larry Hastings2f936352014-08-05 14:04:04 +10003912 if (!result)
3913 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003914#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003916#if HAVE_MKDIRAT
3917 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003918 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003919 else
3920#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003921#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003922 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003923#else
Larry Hastings2f936352014-08-05 14:04:04 +10003924 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003925#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003926 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003927 if (result < 0)
3928 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003929#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003930 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003931}
3932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003933
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003934/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3935#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003936#include <sys/resource.h>
3937#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003938
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003939
3940#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003941/*[clinic input]
3942os.nice
3943
3944 increment: int
3945 /
3946
3947Add increment to the priority of process and return the new priority.
3948[clinic start generated code]*/
3949
Larry Hastings2f936352014-08-05 14:04:04 +10003950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003951os_nice_impl(PyObject *module, int increment)
3952/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003953{
3954 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003955
Victor Stinner8c62be82010-05-06 00:08:46 +00003956 /* There are two flavours of 'nice': one that returns the new
3957 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07003958 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00003959 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003960
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 If we are of the nice family that returns the new priority, we
3962 need to clear errno before the call, and check if errno is filled
3963 before calling posix_error() on a returnvalue of -1, because the
3964 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003965
Victor Stinner8c62be82010-05-06 00:08:46 +00003966 errno = 0;
3967 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003968#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003969 if (value == 0)
3970 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003971#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003972 if (value == -1 && errno != 0)
3973 /* either nice() or getpriority() returned an error */
3974 return posix_error();
3975 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003976}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003977#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003978
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003979
3980#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003981/*[clinic input]
3982os.getpriority
3983
3984 which: int
3985 who: int
3986
3987Return program scheduling priority.
3988[clinic start generated code]*/
3989
Larry Hastings2f936352014-08-05 14:04:04 +10003990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003991os_getpriority_impl(PyObject *module, int which, int who)
3992/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003993{
3994 int retval;
3995
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003996 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003997 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003998 if (errno != 0)
3999 return posix_error();
4000 return PyLong_FromLong((long)retval);
4001}
4002#endif /* HAVE_GETPRIORITY */
4003
4004
4005#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004006/*[clinic input]
4007os.setpriority
4008
4009 which: int
4010 who: int
4011 priority: int
4012
4013Set program scheduling priority.
4014[clinic start generated code]*/
4015
Larry Hastings2f936352014-08-05 14:04:04 +10004016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004017os_setpriority_impl(PyObject *module, int which, int who, int priority)
4018/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004019{
4020 int retval;
4021
4022 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004023 if (retval == -1)
4024 return posix_error();
4025 Py_RETURN_NONE;
4026}
4027#endif /* HAVE_SETPRIORITY */
4028
4029
Barry Warsaw53699e91996-12-10 23:23:01 +00004030static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004031internal_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 +00004032{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004033 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004034 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004035
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004036#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004037 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004038 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004039#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004040 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004041#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004042
Larry Hastings9cf065c2012-06-22 16:30:09 -07004043 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4044 (dst_dir_fd != DEFAULT_DIR_FD);
4045#ifndef HAVE_RENAMEAT
4046 if (dir_fd_specified) {
4047 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004048 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004049 }
4050#endif
4051
Larry Hastings9cf065c2012-06-22 16:30:09 -07004052#ifdef MS_WINDOWS
4053 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004054 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004055 Py_END_ALLOW_THREADS
4056
Larry Hastings2f936352014-08-05 14:04:04 +10004057 if (!result)
4058 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004059
4060#else
Steve Dowercc16be82016-09-08 10:35:16 -07004061 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4062 PyErr_Format(PyExc_ValueError,
4063 "%s: src and dst must be the same type", function_name);
4064 return NULL;
4065 }
4066
Larry Hastings9cf065c2012-06-22 16:30:09 -07004067 Py_BEGIN_ALLOW_THREADS
4068#ifdef HAVE_RENAMEAT
4069 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004070 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004071 else
4072#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004073 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004074 Py_END_ALLOW_THREADS
4075
Larry Hastings2f936352014-08-05 14:04:04 +10004076 if (result)
4077 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004079 Py_RETURN_NONE;
4080}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081
Larry Hastings2f936352014-08-05 14:04:04 +10004082
4083/*[clinic input]
4084os.rename
4085
4086 src : path_t
4087 dst : path_t
4088 *
4089 src_dir_fd : dir_fd = None
4090 dst_dir_fd : dir_fd = None
4091
4092Rename a file or directory.
4093
4094If either src_dir_fd or dst_dir_fd is not None, it should be a file
4095 descriptor open to a directory, and the respective path string (src or dst)
4096 should be relative; the path will then be relative to that directory.
4097src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4098 If they are unavailable, using them will raise a NotImplementedError.
4099[clinic start generated code]*/
4100
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004101static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004102os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004103 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004104/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004105{
Larry Hastings2f936352014-08-05 14:04:04 +10004106 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004107}
4108
Larry Hastings2f936352014-08-05 14:04:04 +10004109
4110/*[clinic input]
4111os.replace = os.rename
4112
4113Rename a file or directory, overwriting the destination.
4114
4115If either src_dir_fd or dst_dir_fd is not None, it should be a file
4116 descriptor open to a directory, and the respective path string (src or dst)
4117 should be relative; the path will then be relative to that directory.
4118src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4119 If they are unavailable, using them will raise a NotImplementedError."
4120[clinic start generated code]*/
4121
Larry Hastings2f936352014-08-05 14:04:04 +10004122static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004123os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4124 int dst_dir_fd)
4125/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004126{
4127 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4128}
4129
4130
4131/*[clinic input]
4132os.rmdir
4133
4134 path: path_t
4135 *
4136 dir_fd: dir_fd(requires='unlinkat') = None
4137
4138Remove a directory.
4139
4140If dir_fd is not None, it should be a file descriptor open to a directory,
4141 and path should be relative; path will then be relative to that directory.
4142dir_fd may not be implemented on your platform.
4143 If it is unavailable, using it will raise a NotImplementedError.
4144[clinic start generated code]*/
4145
Larry Hastings2f936352014-08-05 14:04:04 +10004146static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004147os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4148/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004149{
4150 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004151
4152 Py_BEGIN_ALLOW_THREADS
4153#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004154 /* Windows, success=1, UNIX, success=0 */
4155 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004156#else
4157#ifdef HAVE_UNLINKAT
4158 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004159 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004160 else
4161#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004162 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004163#endif
4164 Py_END_ALLOW_THREADS
4165
Larry Hastings2f936352014-08-05 14:04:04 +10004166 if (result)
4167 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004168
Larry Hastings2f936352014-08-05 14:04:04 +10004169 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004170}
4171
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004172
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004173#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004174#ifdef MS_WINDOWS
4175/*[clinic input]
4176os.system -> long
4177
4178 command: Py_UNICODE
4179
4180Execute the command in a subshell.
4181[clinic start generated code]*/
4182
Larry Hastings2f936352014-08-05 14:04:04 +10004183static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004184os_system_impl(PyObject *module, Py_UNICODE *command)
4185/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004186{
4187 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004189 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004190 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004191 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004193 return result;
4194}
4195#else /* MS_WINDOWS */
4196/*[clinic input]
4197os.system -> long
4198
4199 command: FSConverter
4200
4201Execute the command in a subshell.
4202[clinic start generated code]*/
4203
Larry Hastings2f936352014-08-05 14:04:04 +10004204static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004205os_system_impl(PyObject *module, PyObject *command)
4206/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004207{
4208 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004209 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004210 Py_BEGIN_ALLOW_THREADS
4211 result = system(bytes);
4212 Py_END_ALLOW_THREADS
4213 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004214}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004215#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004216#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004218
Larry Hastings2f936352014-08-05 14:04:04 +10004219/*[clinic input]
4220os.umask
4221
4222 mask: int
4223 /
4224
4225Set the current numeric umask and return the previous umask.
4226[clinic start generated code]*/
4227
Larry Hastings2f936352014-08-05 14:04:04 +10004228static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004229os_umask_impl(PyObject *module, int mask)
4230/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004231{
4232 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004233 if (i < 0)
4234 return posix_error();
4235 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004236}
4237
Brian Curtind40e6f72010-07-08 21:39:08 +00004238#ifdef MS_WINDOWS
4239
4240/* override the default DeleteFileW behavior so that directory
4241symlinks can be removed with this function, the same as with
4242Unix symlinks */
4243BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4244{
4245 WIN32_FILE_ATTRIBUTE_DATA info;
4246 WIN32_FIND_DATAW find_data;
4247 HANDLE find_data_handle;
4248 int is_directory = 0;
4249 int is_link = 0;
4250
4251 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4252 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004253
Brian Curtind40e6f72010-07-08 21:39:08 +00004254 /* Get WIN32_FIND_DATA structure for the path to determine if
4255 it is a symlink */
4256 if(is_directory &&
4257 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4258 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4259
4260 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004261 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4262 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4263 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4264 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004265 FindClose(find_data_handle);
4266 }
4267 }
4268 }
4269
4270 if (is_directory && is_link)
4271 return RemoveDirectoryW(lpFileName);
4272
4273 return DeleteFileW(lpFileName);
4274}
4275#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004277
Larry Hastings2f936352014-08-05 14:04:04 +10004278/*[clinic input]
4279os.unlink
4280
4281 path: path_t
4282 *
4283 dir_fd: dir_fd(requires='unlinkat')=None
4284
4285Remove a file (same as remove()).
4286
4287If dir_fd is not None, it should be a file descriptor open to a directory,
4288 and path should be relative; path will then be relative to that directory.
4289dir_fd may not be implemented on your platform.
4290 If it is unavailable, using it will raise a NotImplementedError.
4291
4292[clinic start generated code]*/
4293
Larry Hastings2f936352014-08-05 14:04:04 +10004294static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004295os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4296/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004297{
4298 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004299
4300 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004301 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004302#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004303 /* Windows, success=1, UNIX, success=0 */
4304 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004305#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004306#ifdef HAVE_UNLINKAT
4307 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004308 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004309 else
4310#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004311 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004312#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004313 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004314 Py_END_ALLOW_THREADS
4315
Larry Hastings2f936352014-08-05 14:04:04 +10004316 if (result)
4317 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004318
Larry Hastings2f936352014-08-05 14:04:04 +10004319 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004320}
4321
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004322
Larry Hastings2f936352014-08-05 14:04:04 +10004323/*[clinic input]
4324os.remove = os.unlink
4325
4326Remove a file (same as unlink()).
4327
4328If dir_fd is not None, it should be a file descriptor open to a directory,
4329 and path should be relative; path will then be relative to that directory.
4330dir_fd may not be implemented on your platform.
4331 If it is unavailable, using it will raise a NotImplementedError.
4332[clinic start generated code]*/
4333
Larry Hastings2f936352014-08-05 14:04:04 +10004334static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004335os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4336/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004337{
4338 return os_unlink_impl(module, path, dir_fd);
4339}
4340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004341
Larry Hastings605a62d2012-06-24 04:33:36 -07004342static PyStructSequence_Field uname_result_fields[] = {
4343 {"sysname", "operating system name"},
4344 {"nodename", "name of machine on network (implementation-defined)"},
4345 {"release", "operating system release"},
4346 {"version", "operating system version"},
4347 {"machine", "hardware identifier"},
4348 {NULL}
4349};
4350
4351PyDoc_STRVAR(uname_result__doc__,
4352"uname_result: Result from os.uname().\n\n\
4353This object may be accessed either as a tuple of\n\
4354 (sysname, nodename, release, version, machine),\n\
4355or via the attributes sysname, nodename, release, version, and machine.\n\
4356\n\
4357See os.uname for more information.");
4358
4359static PyStructSequence_Desc uname_result_desc = {
4360 "uname_result", /* name */
4361 uname_result__doc__, /* doc */
4362 uname_result_fields,
4363 5
4364};
4365
4366static PyTypeObject UnameResultType;
4367
4368
4369#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004370/*[clinic input]
4371os.uname
4372
4373Return an object identifying the current operating system.
4374
4375The object behaves like a named tuple with the following fields:
4376 (sysname, nodename, release, version, machine)
4377
4378[clinic start generated code]*/
4379
Larry Hastings2f936352014-08-05 14:04:04 +10004380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004381os_uname_impl(PyObject *module)
4382/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004383{
Victor Stinner8c62be82010-05-06 00:08:46 +00004384 struct utsname u;
4385 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004386 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004387
Victor Stinner8c62be82010-05-06 00:08:46 +00004388 Py_BEGIN_ALLOW_THREADS
4389 res = uname(&u);
4390 Py_END_ALLOW_THREADS
4391 if (res < 0)
4392 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004393
4394 value = PyStructSequence_New(&UnameResultType);
4395 if (value == NULL)
4396 return NULL;
4397
4398#define SET(i, field) \
4399 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004400 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004401 if (!o) { \
4402 Py_DECREF(value); \
4403 return NULL; \
4404 } \
4405 PyStructSequence_SET_ITEM(value, i, o); \
4406 } \
4407
4408 SET(0, u.sysname);
4409 SET(1, u.nodename);
4410 SET(2, u.release);
4411 SET(3, u.version);
4412 SET(4, u.machine);
4413
4414#undef SET
4415
4416 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004417}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004418#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004419
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004420
Larry Hastings9cf065c2012-06-22 16:30:09 -07004421
4422typedef struct {
4423 int now;
4424 time_t atime_s;
4425 long atime_ns;
4426 time_t mtime_s;
4427 long mtime_ns;
4428} utime_t;
4429
4430/*
Victor Stinner484df002014-10-09 13:52:31 +02004431 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004432 * they also intentionally leak the declaration of a pointer named "time"
4433 */
4434#define UTIME_TO_TIMESPEC \
4435 struct timespec ts[2]; \
4436 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004437 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004438 time = NULL; \
4439 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004440 ts[0].tv_sec = ut->atime_s; \
4441 ts[0].tv_nsec = ut->atime_ns; \
4442 ts[1].tv_sec = ut->mtime_s; \
4443 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444 time = ts; \
4445 } \
4446
4447#define UTIME_TO_TIMEVAL \
4448 struct timeval tv[2]; \
4449 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004450 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004451 time = NULL; \
4452 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004453 tv[0].tv_sec = ut->atime_s; \
4454 tv[0].tv_usec = ut->atime_ns / 1000; \
4455 tv[1].tv_sec = ut->mtime_s; \
4456 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004457 time = tv; \
4458 } \
4459
4460#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004461 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004462 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004463 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004464 time = NULL; \
4465 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004466 u.actime = ut->atime_s; \
4467 u.modtime = ut->mtime_s; \
4468 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004469 }
4470
4471#define UTIME_TO_TIME_T \
4472 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004473 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004474 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475 time = NULL; \
4476 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004477 timet[0] = ut->atime_s; \
4478 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004479 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004480 } \
4481
4482
Victor Stinner528a9ab2015-09-03 21:30:26 +02004483#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004484
4485static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004486utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004487{
4488#ifdef HAVE_UTIMENSAT
4489 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4490 UTIME_TO_TIMESPEC;
4491 return utimensat(dir_fd, path, time, flags);
4492#elif defined(HAVE_FUTIMESAT)
4493 UTIME_TO_TIMEVAL;
4494 /*
4495 * follow_symlinks will never be false here;
4496 * we only allow !follow_symlinks and dir_fd together
4497 * if we have utimensat()
4498 */
4499 assert(follow_symlinks);
4500 return futimesat(dir_fd, path, time);
4501#endif
4502}
4503
Larry Hastings2f936352014-08-05 14:04:04 +10004504 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4505#else
4506 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004507#endif
4508
Victor Stinner528a9ab2015-09-03 21:30:26 +02004509#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004510
4511static int
Victor Stinner484df002014-10-09 13:52:31 +02004512utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004513{
4514#ifdef HAVE_FUTIMENS
4515 UTIME_TO_TIMESPEC;
4516 return futimens(fd, time);
4517#else
4518 UTIME_TO_TIMEVAL;
4519 return futimes(fd, time);
4520#endif
4521}
4522
Larry Hastings2f936352014-08-05 14:04:04 +10004523 #define PATH_UTIME_HAVE_FD 1
4524#else
4525 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004526#endif
4527
Victor Stinner5ebae872015-09-22 01:29:33 +02004528#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4529# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4530#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531
Victor Stinner4552ced2015-09-21 22:37:15 +02004532#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004533
4534static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004535utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004536{
4537#ifdef HAVE_UTIMENSAT
4538 UTIME_TO_TIMESPEC;
4539 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4540#else
4541 UTIME_TO_TIMEVAL;
4542 return lutimes(path, time);
4543#endif
4544}
4545
4546#endif
4547
4548#ifndef MS_WINDOWS
4549
4550static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004551utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004552{
4553#ifdef HAVE_UTIMENSAT
4554 UTIME_TO_TIMESPEC;
4555 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4556#elif defined(HAVE_UTIMES)
4557 UTIME_TO_TIMEVAL;
4558 return utimes(path, time);
4559#elif defined(HAVE_UTIME_H)
4560 UTIME_TO_UTIMBUF;
4561 return utime(path, time);
4562#else
4563 UTIME_TO_TIME_T;
4564 return utime(path, time);
4565#endif
4566}
4567
4568#endif
4569
Larry Hastings76ad59b2012-05-03 00:30:07 -07004570static int
4571split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4572{
4573 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004574 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004575 divmod = PyNumber_Divmod(py_long, billion);
4576 if (!divmod)
4577 goto exit;
Miss Islington (bot)329ea4e2018-09-12 12:46:30 -07004578 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4579 PyErr_Format(PyExc_TypeError,
4580 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4581 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4582 goto exit;
4583 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004584 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4585 if ((*s == -1) && PyErr_Occurred())
4586 goto exit;
4587 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004588 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004589 goto exit;
4590
4591 result = 1;
4592exit:
4593 Py_XDECREF(divmod);
4594 return result;
4595}
4596
Larry Hastings2f936352014-08-05 14:04:04 +10004597
4598/*[clinic input]
4599os.utime
4600
4601 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4602 times: object = NULL
4603 *
4604 ns: object = NULL
4605 dir_fd: dir_fd(requires='futimensat') = None
4606 follow_symlinks: bool=True
4607
Martin Panter0ff89092015-09-09 01:56:53 +00004608# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004609
4610Set the access and modified time of path.
4611
4612path may always be specified as a string.
4613On some platforms, path may also be specified as an open file descriptor.
4614 If this functionality is unavailable, using it raises an exception.
4615
4616If times is not None, it must be a tuple (atime, mtime);
4617 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004618If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004619 atime_ns and mtime_ns should be expressed as integer nanoseconds
4620 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004621If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004622Specifying tuples for both times and ns is an error.
4623
4624If dir_fd is not None, it should be a file descriptor open to a directory,
4625 and path should be relative; path will then be relative to that directory.
4626If follow_symlinks is False, and the last element of the path is a symbolic
4627 link, utime will modify the symbolic link itself instead of the file the
4628 link points to.
4629It is an error to use dir_fd or follow_symlinks when specifying path
4630 as an open file descriptor.
4631dir_fd and follow_symlinks may not be available on your platform.
4632 If they are unavailable, using them will raise a NotImplementedError.
4633
4634[clinic start generated code]*/
4635
Larry Hastings2f936352014-08-05 14:04:04 +10004636static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004637os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4638 int dir_fd, int follow_symlinks)
4639/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004640{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641#ifdef MS_WINDOWS
4642 HANDLE hFile;
4643 FILETIME atime, mtime;
4644#else
4645 int result;
4646#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004647
Larry Hastings2f936352014-08-05 14:04:04 +10004648 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004649
Christian Heimesb3c87242013-08-01 00:08:16 +02004650 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004651
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652 if (times && (times != Py_None) && ns) {
4653 PyErr_SetString(PyExc_ValueError,
4654 "utime: you may specify either 'times'"
4655 " or 'ns' but not both");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004656 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004657 }
4658
4659 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004660 time_t a_sec, m_sec;
4661 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004662 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663 PyErr_SetString(PyExc_TypeError,
4664 "utime: 'times' must be either"
4665 " a tuple of two ints or None");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004666 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004667 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004669 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004670 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004671 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004672 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004673 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004674 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004675 utime.atime_s = a_sec;
4676 utime.atime_ns = a_nsec;
4677 utime.mtime_s = m_sec;
4678 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004679 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004680 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004681 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682 PyErr_SetString(PyExc_TypeError,
4683 "utime: 'ns' must be a tuple of two ints");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004684 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004685 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004687 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004689 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 &utime.mtime_s, &utime.mtime_ns)) {
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004691 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004692 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004693 }
4694 else {
4695 /* times and ns are both None/unspecified. use "now". */
4696 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004697 }
4698
Victor Stinner4552ced2015-09-21 22:37:15 +02004699#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004700 if (follow_symlinks_specified("utime", follow_symlinks))
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004701 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004703
Larry Hastings2f936352014-08-05 14:04:04 +10004704 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4705 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4706 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004707 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004708
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709#if !defined(HAVE_UTIMENSAT)
4710 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004711 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712 "utime: cannot use dir_fd and follow_symlinks "
4713 "together on this platform");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004714 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 }
4716#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004717
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004718#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004719 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004720 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4721 NULL, OPEN_EXISTING,
4722 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004723 Py_END_ALLOW_THREADS
4724 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004725 path_error(path);
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004726 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004727 }
4728
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004730 GetSystemTimeAsFileTime(&mtime);
4731 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004732 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004733 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004734 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4735 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004736 }
4737 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4738 /* Avoid putting the file name into the error here,
4739 as that may confuse the user into believing that
4740 something is wrong with the file, when it also
4741 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004742 PyErr_SetFromWindowsErr(0);
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004743 CloseHandle(hFile);
4744 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004745 }
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004746 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004747#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004748 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004749
Victor Stinner4552ced2015-09-21 22:37:15 +02004750#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004752 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004754#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755
Victor Stinner528a9ab2015-09-03 21:30:26 +02004756#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004758 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759 else
4760#endif
4761
Victor Stinner528a9ab2015-09-03 21:30:26 +02004762#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004763 if (path->fd != -1)
4764 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 else
4766#endif
4767
Larry Hastings2f936352014-08-05 14:04:04 +10004768 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769
4770 Py_END_ALLOW_THREADS
4771
4772 if (result < 0) {
4773 /* see previous comment about not putting filename in error here */
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004774 posix_error();
4775 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004776 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004777
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004778#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004779
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004780 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004781}
4782
Guido van Rossum3b066191991-06-04 19:40:25 +00004783/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004784
Larry Hastings2f936352014-08-05 14:04:04 +10004785
4786/*[clinic input]
4787os._exit
4788
4789 status: int
4790
4791Exit to the system with specified status, without normal exit processing.
4792[clinic start generated code]*/
4793
Larry Hastings2f936352014-08-05 14:04:04 +10004794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004795os__exit_impl(PyObject *module, int status)
4796/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004797{
4798 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004799 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004800}
4801
Steve Dowercc16be82016-09-08 10:35:16 -07004802#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4803#define EXECV_CHAR wchar_t
4804#else
4805#define EXECV_CHAR char
4806#endif
4807
Martin v. Löwis114619e2002-10-07 06:44:21 +00004808#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4809static void
Steve Dowercc16be82016-09-08 10:35:16 -07004810free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004811{
Victor Stinner8c62be82010-05-06 00:08:46 +00004812 Py_ssize_t i;
4813 for (i = 0; i < count; i++)
4814 PyMem_Free(array[i]);
4815 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004816}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004817
Berker Peksag81816462016-09-15 20:19:47 +03004818static int
4819fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004820{
Victor Stinner8c62be82010-05-06 00:08:46 +00004821 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004822 PyObject *ub;
4823 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004824#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004825 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004826 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004827 *out = PyUnicode_AsWideCharString(ub, &size);
4828 if (*out)
4829 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004830#else
Berker Peksag81816462016-09-15 20:19:47 +03004831 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004833 size = PyBytes_GET_SIZE(ub);
4834 *out = PyMem_Malloc(size + 1);
4835 if (*out) {
4836 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4837 result = 1;
4838 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004839 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004840#endif
Berker Peksag81816462016-09-15 20:19:47 +03004841 Py_DECREF(ub);
4842 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004843}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004844#endif
4845
Ross Lagerwall7807c352011-03-17 20:20:30 +02004846#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004847static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004848parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4849{
Victor Stinner8c62be82010-05-06 00:08:46 +00004850 Py_ssize_t i, pos, envc;
4851 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004852 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004853 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004854
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 i = PyMapping_Size(env);
4856 if (i < 0)
4857 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004858 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004859 if (envlist == NULL) {
4860 PyErr_NoMemory();
4861 return NULL;
4862 }
4863 envc = 0;
4864 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004865 if (!keys)
4866 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004868 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004869 goto error;
4870 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4871 PyErr_Format(PyExc_TypeError,
4872 "env.keys() or env.values() is not a list");
4873 goto error;
4874 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004875
Victor Stinner8c62be82010-05-06 00:08:46 +00004876 for (pos = 0; pos < i; pos++) {
4877 key = PyList_GetItem(keys, pos);
4878 val = PyList_GetItem(vals, pos);
4879 if (!key || !val)
4880 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004881
Berker Peksag81816462016-09-15 20:19:47 +03004882#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4883 if (!PyUnicode_FSDecoder(key, &key2))
4884 goto error;
4885 if (!PyUnicode_FSDecoder(val, &val2)) {
4886 Py_DECREF(key2);
4887 goto error;
4888 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004889 /* Search from index 1 because on Windows starting '=' is allowed for
4890 defining hidden environment variables. */
4891 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4892 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4893 {
4894 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004895 Py_DECREF(key2);
4896 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004897 goto error;
4898 }
Berker Peksag81816462016-09-15 20:19:47 +03004899 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4900#else
4901 if (!PyUnicode_FSConverter(key, &key2))
4902 goto error;
4903 if (!PyUnicode_FSConverter(val, &val2)) {
4904 Py_DECREF(key2);
4905 goto error;
4906 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004907 if (PyBytes_GET_SIZE(key2) == 0 ||
4908 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4909 {
4910 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004911 Py_DECREF(key2);
4912 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004913 goto error;
4914 }
Berker Peksag81816462016-09-15 20:19:47 +03004915 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4916 PyBytes_AS_STRING(val2));
4917#endif
4918 Py_DECREF(key2);
4919 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004920 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004922
4923 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4924 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004925 goto error;
4926 }
Berker Peksag81816462016-09-15 20:19:47 +03004927
Steve Dowercc16be82016-09-08 10:35:16 -07004928 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 }
4930 Py_DECREF(vals);
4931 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004932
Victor Stinner8c62be82010-05-06 00:08:46 +00004933 envlist[envc] = 0;
4934 *envc_ptr = envc;
4935 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004936
4937error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 Py_XDECREF(keys);
4939 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004940 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004941 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004942}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004943
Steve Dowercc16be82016-09-08 10:35:16 -07004944static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004945parse_arglist(PyObject* argv, Py_ssize_t *argc)
4946{
4947 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004948 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004949 if (argvlist == NULL) {
4950 PyErr_NoMemory();
4951 return NULL;
4952 }
4953 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004954 PyObject* item = PySequence_ITEM(argv, i);
4955 if (item == NULL)
4956 goto fail;
4957 if (!fsconvert_strdup(item, &argvlist[i])) {
4958 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004959 goto fail;
4960 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004961 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004962 }
4963 argvlist[*argc] = NULL;
4964 return argvlist;
4965fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004966 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004967 free_string_array(argvlist, *argc);
4968 return NULL;
4969}
Steve Dowercc16be82016-09-08 10:35:16 -07004970
Ross Lagerwall7807c352011-03-17 20:20:30 +02004971#endif
4972
Larry Hastings2f936352014-08-05 14:04:04 +10004973
Ross Lagerwall7807c352011-03-17 20:20:30 +02004974#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004975/*[clinic input]
4976os.execv
4977
Steve Dowercc16be82016-09-08 10:35:16 -07004978 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004979 Path of executable file.
4980 argv: object
4981 Tuple or list of strings.
4982 /
4983
4984Execute an executable path with arguments, replacing current process.
4985[clinic start generated code]*/
4986
Larry Hastings2f936352014-08-05 14:04:04 +10004987static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004988os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4989/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004990{
Steve Dowercc16be82016-09-08 10:35:16 -07004991 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004992 Py_ssize_t argc;
4993
4994 /* execv has two arguments: (path, argv), where
4995 argv is a list or tuple of strings. */
4996
Ross Lagerwall7807c352011-03-17 20:20:30 +02004997 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4998 PyErr_SetString(PyExc_TypeError,
4999 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005000 return NULL;
5001 }
5002 argc = PySequence_Size(argv);
5003 if (argc < 1) {
5004 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005005 return NULL;
5006 }
5007
5008 argvlist = parse_arglist(argv, &argc);
5009 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005010 return NULL;
5011 }
Steve Dowerbce26262016-11-19 19:17:26 -08005012 if (!argvlist[0][0]) {
5013 PyErr_SetString(PyExc_ValueError,
5014 "execv() arg 2 first element cannot be empty");
5015 free_string_array(argvlist, argc);
5016 return NULL;
5017 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005018
Steve Dowerbce26262016-11-19 19:17:26 -08005019 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005020#ifdef HAVE_WEXECV
5021 _wexecv(path->wide, argvlist);
5022#else
5023 execv(path->narrow, argvlist);
5024#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005025 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005026
5027 /* If we get here it's definitely an error */
5028
5029 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005030 return posix_error();
5031}
5032
Larry Hastings2f936352014-08-05 14:04:04 +10005033
5034/*[clinic input]
5035os.execve
5036
5037 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5038 Path of executable file.
5039 argv: object
5040 Tuple or list of strings.
5041 env: object
5042 Dictionary of strings mapping to strings.
5043
5044Execute an executable path with arguments, replacing current process.
5045[clinic start generated code]*/
5046
Larry Hastings2f936352014-08-05 14:04:04 +10005047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005048os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5049/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005050{
Steve Dowercc16be82016-09-08 10:35:16 -07005051 EXECV_CHAR **argvlist = NULL;
5052 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005054
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 /* execve has three arguments: (path, argv, env), where
5056 argv is a list or tuple of strings and env is a dictionary
5057 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005058
Ross Lagerwall7807c352011-03-17 20:20:30 +02005059 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005060 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005061 "execve: argv must be a tuple or list");
5062 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005064 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005065 if (argc < 1) {
5066 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5067 return NULL;
5068 }
5069
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 if (!PyMapping_Check(env)) {
5071 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005072 "execve: environment must be a mapping object");
5073 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005075
Ross Lagerwall7807c352011-03-17 20:20:30 +02005076 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005077 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005078 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005079 }
Steve Dowerbce26262016-11-19 19:17:26 -08005080 if (!argvlist[0][0]) {
5081 PyErr_SetString(PyExc_ValueError,
5082 "execve: argv first element cannot be empty");
5083 goto fail;
5084 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005085
Victor Stinner8c62be82010-05-06 00:08:46 +00005086 envlist = parse_envlist(env, &envc);
5087 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005088 goto fail;
5089
Steve Dowerbce26262016-11-19 19:17:26 -08005090 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005091#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005092 if (path->fd > -1)
5093 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005094 else
5095#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005096#ifdef HAVE_WEXECV
5097 _wexecve(path->wide, argvlist, envlist);
5098#else
Larry Hastings2f936352014-08-05 14:04:04 +10005099 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005100#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005101 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005102
5103 /* If we get here it's definitely an error */
5104
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07005105 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005106
Steve Dowercc16be82016-09-08 10:35:16 -07005107 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005108 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005109 if (argvlist)
5110 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005111 return NULL;
5112}
Steve Dowercc16be82016-09-08 10:35:16 -07005113
Larry Hastings9cf065c2012-06-22 16:30:09 -07005114#endif /* HAVE_EXECV */
5115
Steve Dowercc16be82016-09-08 10:35:16 -07005116#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005117/*[clinic input]
5118os.spawnv
5119
5120 mode: int
5121 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005122 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005123 Path of executable file.
5124 argv: object
5125 Tuple or list of strings.
5126 /
5127
5128Execute the program specified by path in a new process.
5129[clinic start generated code]*/
5130
Larry Hastings2f936352014-08-05 14:04:04 +10005131static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005132os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5133/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005134{
Steve Dowercc16be82016-09-08 10:35:16 -07005135 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005136 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005137 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005138 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005139 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005140
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 /* spawnv has three arguments: (mode, path, argv), where
5142 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005143
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 if (PyList_Check(argv)) {
5145 argc = PyList_Size(argv);
5146 getitem = PyList_GetItem;
5147 }
5148 else if (PyTuple_Check(argv)) {
5149 argc = PyTuple_Size(argv);
5150 getitem = PyTuple_GetItem;
5151 }
5152 else {
5153 PyErr_SetString(PyExc_TypeError,
5154 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 return NULL;
5156 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005157 if (argc == 0) {
5158 PyErr_SetString(PyExc_ValueError,
5159 "spawnv() arg 2 cannot be empty");
5160 return NULL;
5161 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005162
Steve Dowercc16be82016-09-08 10:35:16 -07005163 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005165 return PyErr_NoMemory();
5166 }
5167 for (i = 0; i < argc; i++) {
5168 if (!fsconvert_strdup((*getitem)(argv, i),
5169 &argvlist[i])) {
5170 free_string_array(argvlist, i);
5171 PyErr_SetString(
5172 PyExc_TypeError,
5173 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005174 return NULL;
5175 }
Steve Dower93ff8722016-11-19 19:03:54 -08005176 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005177 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005178 PyErr_SetString(
5179 PyExc_ValueError,
5180 "spawnv() arg 2 first element cannot be empty");
5181 return NULL;
5182 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005183 }
5184 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005185
Victor Stinner8c62be82010-05-06 00:08:46 +00005186 if (mode == _OLD_P_OVERLAY)
5187 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005188
Victor Stinner8c62be82010-05-06 00:08:46 +00005189 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005190 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005191#ifdef HAVE_WSPAWNV
5192 spawnval = _wspawnv(mode, path->wide, argvlist);
5193#else
5194 spawnval = _spawnv(mode, path->narrow, argvlist);
5195#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005196 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005197 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005198
Victor Stinner8c62be82010-05-06 00:08:46 +00005199 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005200
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 if (spawnval == -1)
5202 return posix_error();
5203 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005204 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005205}
5206
Larry Hastings2f936352014-08-05 14:04:04 +10005207/*[clinic input]
5208os.spawnve
5209
5210 mode: int
5211 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005212 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005213 Path of executable file.
5214 argv: object
5215 Tuple or list of strings.
5216 env: object
5217 Dictionary of strings mapping to strings.
5218 /
5219
5220Execute the program specified by path in a new process.
5221[clinic start generated code]*/
5222
Larry Hastings2f936352014-08-05 14:04:04 +10005223static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005224os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005225 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005226/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005227{
Steve Dowercc16be82016-09-08 10:35:16 -07005228 EXECV_CHAR **argvlist;
5229 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005230 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005231 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005232 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005233 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005234 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005235
Victor Stinner8c62be82010-05-06 00:08:46 +00005236 /* spawnve has four arguments: (mode, path, argv, env), where
5237 argv is a list or tuple of strings and env is a dictionary
5238 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005239
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 if (PyList_Check(argv)) {
5241 argc = PyList_Size(argv);
5242 getitem = PyList_GetItem;
5243 }
5244 else if (PyTuple_Check(argv)) {
5245 argc = PyTuple_Size(argv);
5246 getitem = PyTuple_GetItem;
5247 }
5248 else {
5249 PyErr_SetString(PyExc_TypeError,
5250 "spawnve() arg 2 must be a tuple or list");
5251 goto fail_0;
5252 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005253 if (argc == 0) {
5254 PyErr_SetString(PyExc_ValueError,
5255 "spawnve() arg 2 cannot be empty");
5256 goto fail_0;
5257 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005258 if (!PyMapping_Check(env)) {
5259 PyErr_SetString(PyExc_TypeError,
5260 "spawnve() arg 3 must be a mapping object");
5261 goto fail_0;
5262 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005263
Steve Dowercc16be82016-09-08 10:35:16 -07005264 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 if (argvlist == NULL) {
5266 PyErr_NoMemory();
5267 goto fail_0;
5268 }
5269 for (i = 0; i < argc; i++) {
5270 if (!fsconvert_strdup((*getitem)(argv, i),
5271 &argvlist[i]))
5272 {
5273 lastarg = i;
5274 goto fail_1;
5275 }
Steve Dowerbce26262016-11-19 19:17:26 -08005276 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005277 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005278 PyErr_SetString(
5279 PyExc_ValueError,
5280 "spawnv() arg 2 first element cannot be empty");
5281 goto fail_1;
5282 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 }
5284 lastarg = argc;
5285 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005286
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 envlist = parse_envlist(env, &envc);
5288 if (envlist == NULL)
5289 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005290
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 if (mode == _OLD_P_OVERLAY)
5292 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005293
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005295 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005296#ifdef HAVE_WSPAWNV
5297 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5298#else
5299 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5300#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005301 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005302 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005303
Victor Stinner8c62be82010-05-06 00:08:46 +00005304 if (spawnval == -1)
5305 (void) posix_error();
5306 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005307 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005308
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 while (--envc >= 0)
5310 PyMem_DEL(envlist[envc]);
5311 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005312 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005313 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005314 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005316}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005317
Guido van Rossuma1065681999-01-25 23:20:23 +00005318#endif /* HAVE_SPAWNV */
5319
5320
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005321#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005322
5323/* Helper function to validate arguments.
5324 Returns 0 on success. non-zero on failure with a TypeError raised.
5325 If obj is non-NULL it must be callable. */
5326static int
5327check_null_or_callable(PyObject *obj, const char* obj_name)
5328{
5329 if (obj && !PyCallable_Check(obj)) {
5330 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5331 obj_name, Py_TYPE(obj)->tp_name);
5332 return -1;
5333 }
5334 return 0;
5335}
5336
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005337/*[clinic input]
5338os.register_at_fork
5339
Gregory P. Smith163468a2017-05-29 10:03:41 -07005340 *
5341 before: object=NULL
5342 A callable to be called in the parent before the fork() syscall.
5343 after_in_child: object=NULL
5344 A callable to be called in the child after fork().
5345 after_in_parent: object=NULL
5346 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005347
Gregory P. Smith163468a2017-05-29 10:03:41 -07005348Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005349
Gregory P. Smith163468a2017-05-29 10:03:41 -07005350'before' callbacks are called in reverse order.
5351'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005352
5353[clinic start generated code]*/
5354
5355static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005356os_register_at_fork_impl(PyObject *module, PyObject *before,
5357 PyObject *after_in_child, PyObject *after_in_parent)
5358/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005359{
5360 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005361
Gregory P. Smith163468a2017-05-29 10:03:41 -07005362 if (!before && !after_in_child && !after_in_parent) {
5363 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5364 return NULL;
5365 }
5366 if (check_null_or_callable(before, "before") ||
5367 check_null_or_callable(after_in_child, "after_in_child") ||
5368 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005369 return NULL;
5370 }
5371 interp = PyThreadState_Get()->interp;
5372
Gregory P. Smith163468a2017-05-29 10:03:41 -07005373 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005374 return NULL;
5375 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005376 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005377 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005378 }
5379 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5380 return NULL;
5381 }
5382 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005383}
5384#endif /* HAVE_FORK */
5385
5386
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005387#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005388/*[clinic input]
5389os.fork1
5390
5391Fork a child process with a single multiplexed (i.e., not bound) thread.
5392
5393Return 0 to child process and PID of child to parent process.
5394[clinic start generated code]*/
5395
Larry Hastings2f936352014-08-05 14:04:04 +10005396static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005397os_fork1_impl(PyObject *module)
5398/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005399{
Victor Stinner8c62be82010-05-06 00:08:46 +00005400 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005401
5402 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005403 pid = fork1();
5404 if (pid == 0) {
5405 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005406 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 } else {
5408 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005409 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 }
5411 if (pid == -1)
5412 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005413 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005414}
Larry Hastings2f936352014-08-05 14:04:04 +10005415#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005416
5417
Guido van Rossumad0ee831995-03-01 10:34:45 +00005418#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005419/*[clinic input]
5420os.fork
5421
5422Fork a child process.
5423
5424Return 0 to child process and PID of child to parent process.
5425[clinic start generated code]*/
5426
Larry Hastings2f936352014-08-05 14:04:04 +10005427static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005428os_fork_impl(PyObject *module)
5429/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005430{
Victor Stinner8c62be82010-05-06 00:08:46 +00005431 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005432
5433 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005434 pid = fork();
5435 if (pid == 0) {
5436 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005437 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005438 } else {
5439 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005440 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005441 }
5442 if (pid == -1)
5443 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005444 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005445}
Larry Hastings2f936352014-08-05 14:04:04 +10005446#endif /* HAVE_FORK */
5447
Guido van Rossum85e3b011991-06-03 12:42:10 +00005448
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005449#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005450#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005451/*[clinic input]
5452os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005453
Larry Hastings2f936352014-08-05 14:04:04 +10005454 policy: int
5455
5456Get the maximum scheduling priority for policy.
5457[clinic start generated code]*/
5458
Larry Hastings2f936352014-08-05 14:04:04 +10005459static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005460os_sched_get_priority_max_impl(PyObject *module, int policy)
5461/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005462{
5463 int max;
5464
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005465 max = sched_get_priority_max(policy);
5466 if (max < 0)
5467 return posix_error();
5468 return PyLong_FromLong(max);
5469}
5470
Larry Hastings2f936352014-08-05 14:04:04 +10005471
5472/*[clinic input]
5473os.sched_get_priority_min
5474
5475 policy: int
5476
5477Get the minimum scheduling priority for policy.
5478[clinic start generated code]*/
5479
Larry Hastings2f936352014-08-05 14:04:04 +10005480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005481os_sched_get_priority_min_impl(PyObject *module, int policy)
5482/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005483{
5484 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005485 if (min < 0)
5486 return posix_error();
5487 return PyLong_FromLong(min);
5488}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005489#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5490
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005491
Larry Hastings2f936352014-08-05 14:04:04 +10005492#ifdef HAVE_SCHED_SETSCHEDULER
5493/*[clinic input]
5494os.sched_getscheduler
5495 pid: pid_t
5496 /
5497
5498Get the scheduling policy for the process identifiedy by pid.
5499
5500Passing 0 for pid returns the scheduling policy for the calling process.
5501[clinic start generated code]*/
5502
Larry Hastings2f936352014-08-05 14:04:04 +10005503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005504os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5505/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005506{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005507 int policy;
5508
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005509 policy = sched_getscheduler(pid);
5510 if (policy < 0)
5511 return posix_error();
5512 return PyLong_FromLong(policy);
5513}
Larry Hastings2f936352014-08-05 14:04:04 +10005514#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005515
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005516
5517#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005518/*[clinic input]
5519class os.sched_param "PyObject *" "&SchedParamType"
5520
5521@classmethod
5522os.sched_param.__new__
5523
5524 sched_priority: object
5525 A scheduling parameter.
5526
5527Current has only one field: sched_priority");
5528[clinic start generated code]*/
5529
Larry Hastings2f936352014-08-05 14:04:04 +10005530static PyObject *
5531os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005532/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005533{
5534 PyObject *res;
5535
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005536 res = PyStructSequence_New(type);
5537 if (!res)
5538 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005539 Py_INCREF(sched_priority);
5540 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005541 return res;
5542}
5543
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005544
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005545PyDoc_VAR(os_sched_param__doc__);
5546
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005547static PyStructSequence_Field sched_param_fields[] = {
5548 {"sched_priority", "the scheduling priority"},
5549 {0}
5550};
5551
5552static PyStructSequence_Desc sched_param_desc = {
5553 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005554 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005555 sched_param_fields,
5556 1
5557};
5558
5559static int
5560convert_sched_param(PyObject *param, struct sched_param *res)
5561{
5562 long priority;
5563
5564 if (Py_TYPE(param) != &SchedParamType) {
5565 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5566 return 0;
5567 }
5568 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5569 if (priority == -1 && PyErr_Occurred())
5570 return 0;
5571 if (priority > INT_MAX || priority < INT_MIN) {
5572 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5573 return 0;
5574 }
5575 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5576 return 1;
5577}
Larry Hastings2f936352014-08-05 14:04:04 +10005578#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005579
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005580
5581#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005582/*[clinic input]
5583os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005584
Larry Hastings2f936352014-08-05 14:04:04 +10005585 pid: pid_t
5586 policy: int
5587 param: sched_param
5588 /
5589
5590Set the scheduling policy for the process identified by pid.
5591
5592If pid is 0, the calling process is changed.
5593param is an instance of sched_param.
5594[clinic start generated code]*/
5595
Larry Hastings2f936352014-08-05 14:04:04 +10005596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005597os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005598 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005599/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005600{
Jesus Cea9c822272011-09-10 01:40:52 +02005601 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005602 ** sched_setscheduler() returns 0 in Linux, but the previous
5603 ** scheduling policy under Solaris/Illumos, and others.
5604 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005605 */
Larry Hastings2f936352014-08-05 14:04:04 +10005606 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005607 return posix_error();
5608 Py_RETURN_NONE;
5609}
Larry Hastings2f936352014-08-05 14:04:04 +10005610#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005611
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005612
5613#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005614/*[clinic input]
5615os.sched_getparam
5616 pid: pid_t
5617 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005618
Larry Hastings2f936352014-08-05 14:04:04 +10005619Returns scheduling parameters for the process identified by pid.
5620
5621If pid is 0, returns parameters for the calling process.
5622Return value is an instance of sched_param.
5623[clinic start generated code]*/
5624
Larry Hastings2f936352014-08-05 14:04:04 +10005625static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005626os_sched_getparam_impl(PyObject *module, pid_t pid)
5627/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005628{
5629 struct sched_param param;
5630 PyObject *result;
5631 PyObject *priority;
5632
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005633 if (sched_getparam(pid, &param))
5634 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005635 result = PyStructSequence_New(&SchedParamType);
5636 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005637 return NULL;
5638 priority = PyLong_FromLong(param.sched_priority);
5639 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005640 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005641 return NULL;
5642 }
Larry Hastings2f936352014-08-05 14:04:04 +10005643 PyStructSequence_SET_ITEM(result, 0, priority);
5644 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005645}
5646
Larry Hastings2f936352014-08-05 14:04:04 +10005647
5648/*[clinic input]
5649os.sched_setparam
5650 pid: pid_t
5651 param: sched_param
5652 /
5653
5654Set scheduling parameters for the process identified by pid.
5655
5656If pid is 0, sets parameters for the calling process.
5657param should be an instance of sched_param.
5658[clinic start generated code]*/
5659
Larry Hastings2f936352014-08-05 14:04:04 +10005660static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005661os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005662 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005663/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005664{
5665 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005666 return posix_error();
5667 Py_RETURN_NONE;
5668}
Larry Hastings2f936352014-08-05 14:04:04 +10005669#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005670
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005671
5672#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005673/*[clinic input]
5674os.sched_rr_get_interval -> double
5675 pid: pid_t
5676 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005677
Larry Hastings2f936352014-08-05 14:04:04 +10005678Return the round-robin quantum for the process identified by pid, in seconds.
5679
5680Value returned is a float.
5681[clinic start generated code]*/
5682
Larry Hastings2f936352014-08-05 14:04:04 +10005683static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005684os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5685/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005686{
5687 struct timespec interval;
5688 if (sched_rr_get_interval(pid, &interval)) {
5689 posix_error();
5690 return -1.0;
5691 }
5692 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5693}
5694#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005695
Larry Hastings2f936352014-08-05 14:04:04 +10005696
5697/*[clinic input]
5698os.sched_yield
5699
5700Voluntarily relinquish the CPU.
5701[clinic start generated code]*/
5702
Larry Hastings2f936352014-08-05 14:04:04 +10005703static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005704os_sched_yield_impl(PyObject *module)
5705/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005706{
5707 if (sched_yield())
5708 return posix_error();
5709 Py_RETURN_NONE;
5710}
5711
Benjamin Peterson2740af82011-08-02 17:41:34 -05005712#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005713/* The minimum number of CPUs allocated in a cpu_set_t */
5714static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005715
Larry Hastings2f936352014-08-05 14:04:04 +10005716/*[clinic input]
5717os.sched_setaffinity
5718 pid: pid_t
5719 mask : object
5720 /
5721
5722Set the CPU affinity of the process identified by pid to mask.
5723
5724mask should be an iterable of integers identifying CPUs.
5725[clinic start generated code]*/
5726
Larry Hastings2f936352014-08-05 14:04:04 +10005727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005728os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5729/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005730{
Antoine Pitrou84869872012-08-04 16:16:35 +02005731 int ncpus;
5732 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005733 cpu_set_t *cpu_set = NULL;
5734 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005735
Larry Hastings2f936352014-08-05 14:04:04 +10005736 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005737 if (iterator == NULL)
5738 return NULL;
5739
5740 ncpus = NCPUS_START;
5741 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005742 cpu_set = CPU_ALLOC(ncpus);
5743 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005744 PyErr_NoMemory();
5745 goto error;
5746 }
Larry Hastings2f936352014-08-05 14:04:04 +10005747 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005748
5749 while ((item = PyIter_Next(iterator))) {
5750 long cpu;
5751 if (!PyLong_Check(item)) {
5752 PyErr_Format(PyExc_TypeError,
5753 "expected an iterator of ints, "
5754 "but iterator yielded %R",
5755 Py_TYPE(item));
5756 Py_DECREF(item);
5757 goto error;
5758 }
5759 cpu = PyLong_AsLong(item);
5760 Py_DECREF(item);
5761 if (cpu < 0) {
5762 if (!PyErr_Occurred())
5763 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5764 goto error;
5765 }
5766 if (cpu > INT_MAX - 1) {
5767 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5768 goto error;
5769 }
5770 if (cpu >= ncpus) {
5771 /* Grow CPU mask to fit the CPU number */
5772 int newncpus = ncpus;
5773 cpu_set_t *newmask;
5774 size_t newsetsize;
5775 while (newncpus <= cpu) {
5776 if (newncpus > INT_MAX / 2)
5777 newncpus = cpu + 1;
5778 else
5779 newncpus = newncpus * 2;
5780 }
5781 newmask = CPU_ALLOC(newncpus);
5782 if (newmask == NULL) {
5783 PyErr_NoMemory();
5784 goto error;
5785 }
5786 newsetsize = CPU_ALLOC_SIZE(newncpus);
5787 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005788 memcpy(newmask, cpu_set, setsize);
5789 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005790 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005791 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005792 ncpus = newncpus;
5793 }
Larry Hastings2f936352014-08-05 14:04:04 +10005794 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005795 }
5796 Py_CLEAR(iterator);
5797
Larry Hastings2f936352014-08-05 14:04:04 +10005798 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005799 posix_error();
5800 goto error;
5801 }
Larry Hastings2f936352014-08-05 14:04:04 +10005802 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005803 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005804
5805error:
Larry Hastings2f936352014-08-05 14:04:04 +10005806 if (cpu_set)
5807 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005808 Py_XDECREF(iterator);
5809 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005810}
5811
Larry Hastings2f936352014-08-05 14:04:04 +10005812
5813/*[clinic input]
5814os.sched_getaffinity
5815 pid: pid_t
5816 /
5817
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005818Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005819
5820The affinity is returned as a set of CPU identifiers.
5821[clinic start generated code]*/
5822
Larry Hastings2f936352014-08-05 14:04:04 +10005823static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005824os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005825/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005826{
Antoine Pitrou84869872012-08-04 16:16:35 +02005827 int cpu, ncpus, count;
5828 size_t setsize;
5829 cpu_set_t *mask = NULL;
5830 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005831
Antoine Pitrou84869872012-08-04 16:16:35 +02005832 ncpus = NCPUS_START;
5833 while (1) {
5834 setsize = CPU_ALLOC_SIZE(ncpus);
5835 mask = CPU_ALLOC(ncpus);
5836 if (mask == NULL)
5837 return PyErr_NoMemory();
5838 if (sched_getaffinity(pid, setsize, mask) == 0)
5839 break;
5840 CPU_FREE(mask);
5841 if (errno != EINVAL)
5842 return posix_error();
5843 if (ncpus > INT_MAX / 2) {
5844 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5845 "a large enough CPU set");
5846 return NULL;
5847 }
5848 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005849 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005850
5851 res = PySet_New(NULL);
5852 if (res == NULL)
5853 goto error;
5854 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5855 if (CPU_ISSET_S(cpu, setsize, mask)) {
5856 PyObject *cpu_num = PyLong_FromLong(cpu);
5857 --count;
5858 if (cpu_num == NULL)
5859 goto error;
5860 if (PySet_Add(res, cpu_num)) {
5861 Py_DECREF(cpu_num);
5862 goto error;
5863 }
5864 Py_DECREF(cpu_num);
5865 }
5866 }
5867 CPU_FREE(mask);
5868 return res;
5869
5870error:
5871 if (mask)
5872 CPU_FREE(mask);
5873 Py_XDECREF(res);
5874 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005875}
5876
Benjamin Peterson2740af82011-08-02 17:41:34 -05005877#endif /* HAVE_SCHED_SETAFFINITY */
5878
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005879#endif /* HAVE_SCHED_H */
5880
Larry Hastings2f936352014-08-05 14:04:04 +10005881
Neal Norwitzb59798b2003-03-21 01:43:31 +00005882/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005883/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5884#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005885#define DEV_PTY_FILE "/dev/ptc"
5886#define HAVE_DEV_PTMX
5887#else
5888#define DEV_PTY_FILE "/dev/ptmx"
5889#endif
5890
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005891#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005892#ifdef HAVE_PTY_H
5893#include <pty.h>
5894#else
5895#ifdef HAVE_LIBUTIL_H
5896#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005897#else
5898#ifdef HAVE_UTIL_H
5899#include <util.h>
5900#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005901#endif /* HAVE_LIBUTIL_H */
5902#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005903#ifdef HAVE_STROPTS_H
5904#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005905#endif
Miss Islington (bot)f0616ce2018-02-14 13:06:46 -08005906#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005907
Larry Hastings2f936352014-08-05 14:04:04 +10005908
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005909#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005910/*[clinic input]
5911os.openpty
5912
5913Open a pseudo-terminal.
5914
5915Return a tuple of (master_fd, slave_fd) containing open file descriptors
5916for both the master and slave ends.
5917[clinic start generated code]*/
5918
Larry Hastings2f936352014-08-05 14:04:04 +10005919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005920os_openpty_impl(PyObject *module)
5921/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005922{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005923 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005924#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005926#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005927#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005928 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005929#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005930 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005931#endif
5932#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005933
Thomas Wouters70c21a12000-07-14 14:28:33 +00005934#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005936 goto posix_error;
5937
5938 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5939 goto error;
5940 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5941 goto error;
5942
Neal Norwitzb59798b2003-03-21 01:43:31 +00005943#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5945 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005946 goto posix_error;
5947 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5948 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005949
Victor Stinnerdaf45552013-08-28 00:53:59 +02005950 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005952 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005953
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005954#else
Victor Stinner000de532013-11-25 23:19:58 +01005955 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005956 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005957 goto posix_error;
5958
Victor Stinner8c62be82010-05-06 00:08:46 +00005959 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005960
Victor Stinner8c62be82010-05-06 00:08:46 +00005961 /* change permission of slave */
5962 if (grantpt(master_fd) < 0) {
5963 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005964 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005966
Victor Stinner8c62be82010-05-06 00:08:46 +00005967 /* unlock slave */
5968 if (unlockpt(master_fd) < 0) {
5969 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005970 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005971 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005972
Victor Stinner8c62be82010-05-06 00:08:46 +00005973 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005974
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 slave_name = ptsname(master_fd); /* get name of slave */
5976 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005977 goto posix_error;
5978
5979 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005980 if (slave_fd == -1)
5981 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005982
5983 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5984 goto posix_error;
5985
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005986#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005987 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5988 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005989#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005991#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005992#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005993#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005994
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005996
Victor Stinnerdaf45552013-08-28 00:53:59 +02005997posix_error:
5998 posix_error();
5999error:
6000 if (master_fd != -1)
6001 close(master_fd);
6002 if (slave_fd != -1)
6003 close(slave_fd);
6004 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006005}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006006#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006007
Larry Hastings2f936352014-08-05 14:04:04 +10006008
Fred Drake8cef4cf2000-06-28 16:40:38 +00006009#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006010/*[clinic input]
6011os.forkpty
6012
6013Fork a new process with a new pseudo-terminal as controlling tty.
6014
6015Returns a tuple of (pid, master_fd).
6016Like fork(), return pid of 0 to the child process,
6017and pid of child to the parent process.
6018To both, return fd of newly opened pseudo-terminal.
6019[clinic start generated code]*/
6020
Larry Hastings2f936352014-08-05 14:04:04 +10006021static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006022os_forkpty_impl(PyObject *module)
6023/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006024{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006025 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006026 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006027
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006028 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006029 pid = forkpty(&master_fd, NULL, NULL, NULL);
6030 if (pid == 0) {
6031 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006032 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 } else {
6034 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006035 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 }
6037 if (pid == -1)
6038 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006039 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006040}
Larry Hastings2f936352014-08-05 14:04:04 +10006041#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006042
Ross Lagerwall7807c352011-03-17 20:20:30 +02006043
Guido van Rossumad0ee831995-03-01 10:34:45 +00006044#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006045/*[clinic input]
6046os.getegid
6047
6048Return the current process's effective group id.
6049[clinic start generated code]*/
6050
Larry Hastings2f936352014-08-05 14:04:04 +10006051static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006052os_getegid_impl(PyObject *module)
6053/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006054{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006055 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006056}
Larry Hastings2f936352014-08-05 14:04:04 +10006057#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006059
Guido van Rossumad0ee831995-03-01 10:34:45 +00006060#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006061/*[clinic input]
6062os.geteuid
6063
6064Return the current process's effective user id.
6065[clinic start generated code]*/
6066
Larry Hastings2f936352014-08-05 14:04:04 +10006067static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006068os_geteuid_impl(PyObject *module)
6069/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006070{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006071 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006072}
Larry Hastings2f936352014-08-05 14:04:04 +10006073#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006075
Guido van Rossumad0ee831995-03-01 10:34:45 +00006076#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006077/*[clinic input]
6078os.getgid
6079
6080Return the current process's group id.
6081[clinic start generated code]*/
6082
Larry Hastings2f936352014-08-05 14:04:04 +10006083static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006084os_getgid_impl(PyObject *module)
6085/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006086{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006087 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006088}
Larry Hastings2f936352014-08-05 14:04:04 +10006089#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006090
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006091
Berker Peksag39404992016-09-15 20:45:16 +03006092#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006093/*[clinic input]
6094os.getpid
6095
6096Return the current process id.
6097[clinic start generated code]*/
6098
Larry Hastings2f936352014-08-05 14:04:04 +10006099static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006100os_getpid_impl(PyObject *module)
6101/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006102{
Victor Stinner8c62be82010-05-06 00:08:46 +00006103 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006104}
Berker Peksag39404992016-09-15 20:45:16 +03006105#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006106
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006107#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006108
6109/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006110PyDoc_STRVAR(posix_getgrouplist__doc__,
6111"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6112Returns a list of groups to which a user belongs.\n\n\
6113 user: username to lookup\n\
6114 group: base group id of the user");
6115
6116static PyObject *
6117posix_getgrouplist(PyObject *self, PyObject *args)
6118{
6119#ifdef NGROUPS_MAX
6120#define MAX_GROUPS NGROUPS_MAX
6121#else
6122 /* defined to be 16 on Solaris7, so this should be a small number */
6123#define MAX_GROUPS 64
6124#endif
6125
6126 const char *user;
6127 int i, ngroups;
6128 PyObject *list;
6129#ifdef __APPLE__
6130 int *groups, basegid;
6131#else
6132 gid_t *groups, basegid;
6133#endif
6134 ngroups = MAX_GROUPS;
6135
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006136#ifdef __APPLE__
6137 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006138 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006139#else
6140 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6141 _Py_Gid_Converter, &basegid))
6142 return NULL;
6143#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006144
6145#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006146 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006147#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006148 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006149#endif
6150 if (groups == NULL)
6151 return PyErr_NoMemory();
6152
6153 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6154 PyMem_Del(groups);
6155 return posix_error();
6156 }
6157
6158 list = PyList_New(ngroups);
6159 if (list == NULL) {
6160 PyMem_Del(groups);
6161 return NULL;
6162 }
6163
6164 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006165#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006166 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006167#else
6168 PyObject *o = _PyLong_FromGid(groups[i]);
6169#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006170 if (o == NULL) {
6171 Py_DECREF(list);
6172 PyMem_Del(groups);
6173 return NULL;
6174 }
6175 PyList_SET_ITEM(list, i, o);
6176 }
6177
6178 PyMem_Del(groups);
6179
6180 return list;
6181}
Larry Hastings2f936352014-08-05 14:04:04 +10006182#endif /* HAVE_GETGROUPLIST */
6183
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006184
Fred Drakec9680921999-12-13 16:37:25 +00006185#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006186/*[clinic input]
6187os.getgroups
6188
6189Return list of supplemental group IDs for the process.
6190[clinic start generated code]*/
6191
Larry Hastings2f936352014-08-05 14:04:04 +10006192static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006193os_getgroups_impl(PyObject *module)
6194/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006195{
6196 PyObject *result = NULL;
6197
Fred Drakec9680921999-12-13 16:37:25 +00006198#ifdef NGROUPS_MAX
6199#define MAX_GROUPS NGROUPS_MAX
6200#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006201 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006202#define MAX_GROUPS 64
6203#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006205
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006206 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006207 * This is a helper variable to store the intermediate result when
6208 * that happens.
6209 *
6210 * To keep the code readable the OSX behaviour is unconditional,
6211 * according to the POSIX spec this should be safe on all unix-y
6212 * systems.
6213 */
6214 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006215 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006216
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006217#ifdef __APPLE__
6218 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6219 * there are more groups than can fit in grouplist. Therefore, on OS X
6220 * always first call getgroups with length 0 to get the actual number
6221 * of groups.
6222 */
6223 n = getgroups(0, NULL);
6224 if (n < 0) {
6225 return posix_error();
6226 } else if (n <= MAX_GROUPS) {
6227 /* groups will fit in existing array */
6228 alt_grouplist = grouplist;
6229 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006230 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006231 if (alt_grouplist == NULL) {
6232 errno = EINVAL;
6233 return posix_error();
6234 }
6235 }
6236
6237 n = getgroups(n, alt_grouplist);
6238 if (n == -1) {
6239 if (alt_grouplist != grouplist) {
6240 PyMem_Free(alt_grouplist);
6241 }
6242 return posix_error();
6243 }
6244#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006245 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006246 if (n < 0) {
6247 if (errno == EINVAL) {
6248 n = getgroups(0, NULL);
6249 if (n == -1) {
6250 return posix_error();
6251 }
6252 if (n == 0) {
6253 /* Avoid malloc(0) */
6254 alt_grouplist = grouplist;
6255 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006256 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006257 if (alt_grouplist == NULL) {
6258 errno = EINVAL;
6259 return posix_error();
6260 }
6261 n = getgroups(n, alt_grouplist);
6262 if (n == -1) {
6263 PyMem_Free(alt_grouplist);
6264 return posix_error();
6265 }
6266 }
6267 } else {
6268 return posix_error();
6269 }
6270 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006271#endif
6272
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006273 result = PyList_New(n);
6274 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 int i;
6276 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006277 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006278 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006279 Py_DECREF(result);
6280 result = NULL;
6281 break;
Fred Drakec9680921999-12-13 16:37:25 +00006282 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006283 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006284 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006285 }
6286
6287 if (alt_grouplist != grouplist) {
6288 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006289 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006290
Fred Drakec9680921999-12-13 16:37:25 +00006291 return result;
6292}
Larry Hastings2f936352014-08-05 14:04:04 +10006293#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006294
Antoine Pitroub7572f02009-12-02 20:46:48 +00006295#ifdef HAVE_INITGROUPS
6296PyDoc_STRVAR(posix_initgroups__doc__,
6297"initgroups(username, gid) -> None\n\n\
6298Call the system initgroups() to initialize the group access list with all of\n\
6299the groups of which the specified username is a member, plus the specified\n\
6300group id.");
6301
Larry Hastings2f936352014-08-05 14:04:04 +10006302/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006303static PyObject *
6304posix_initgroups(PyObject *self, PyObject *args)
6305{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006306 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006307 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006308 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006309#ifdef __APPLE__
6310 int gid;
6311#else
6312 gid_t gid;
6313#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006314
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006315#ifdef __APPLE__
6316 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6317 PyUnicode_FSConverter, &oname,
6318 &gid))
6319#else
6320 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6321 PyUnicode_FSConverter, &oname,
6322 _Py_Gid_Converter, &gid))
6323#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006325 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006326
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006327 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006328 Py_DECREF(oname);
6329 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006330 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006331
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006332 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006333}
Larry Hastings2f936352014-08-05 14:04:04 +10006334#endif /* HAVE_INITGROUPS */
6335
Antoine Pitroub7572f02009-12-02 20:46:48 +00006336
Martin v. Löwis606edc12002-06-13 21:09:11 +00006337#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006338/*[clinic input]
6339os.getpgid
6340
6341 pid: pid_t
6342
6343Call the system call getpgid(), and return the result.
6344[clinic start generated code]*/
6345
Larry Hastings2f936352014-08-05 14:04:04 +10006346static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006347os_getpgid_impl(PyObject *module, pid_t pid)
6348/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006349{
6350 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006351 if (pgid < 0)
6352 return posix_error();
6353 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006354}
6355#endif /* HAVE_GETPGID */
6356
6357
Guido van Rossumb6775db1994-08-01 11:34:53 +00006358#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006359/*[clinic input]
6360os.getpgrp
6361
6362Return the current process group id.
6363[clinic start generated code]*/
6364
Larry Hastings2f936352014-08-05 14:04:04 +10006365static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006366os_getpgrp_impl(PyObject *module)
6367/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006368{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006369#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006370 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006371#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006372 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006373#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006374}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006375#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006376
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006377
Guido van Rossumb6775db1994-08-01 11:34:53 +00006378#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006379/*[clinic input]
6380os.setpgrp
6381
6382Make the current process the leader of its process group.
6383[clinic start generated code]*/
6384
Larry Hastings2f936352014-08-05 14:04:04 +10006385static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006386os_setpgrp_impl(PyObject *module)
6387/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006388{
Guido van Rossum64933891994-10-20 21:56:42 +00006389#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006391#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006393#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006394 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006395 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006396}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006397#endif /* HAVE_SETPGRP */
6398
Guido van Rossumad0ee831995-03-01 10:34:45 +00006399#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006400
6401#ifdef MS_WINDOWS
6402#include <tlhelp32.h>
6403
6404static PyObject*
6405win32_getppid()
6406{
6407 HANDLE snapshot;
6408 pid_t mypid;
6409 PyObject* result = NULL;
6410 BOOL have_record;
6411 PROCESSENTRY32 pe;
6412
6413 mypid = getpid(); /* This function never fails */
6414
6415 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6416 if (snapshot == INVALID_HANDLE_VALUE)
6417 return PyErr_SetFromWindowsErr(GetLastError());
6418
6419 pe.dwSize = sizeof(pe);
6420 have_record = Process32First(snapshot, &pe);
6421 while (have_record) {
6422 if (mypid == (pid_t)pe.th32ProcessID) {
6423 /* We could cache the ulong value in a static variable. */
6424 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6425 break;
6426 }
6427
6428 have_record = Process32Next(snapshot, &pe);
6429 }
6430
6431 /* If our loop exits and our pid was not found (result will be NULL)
6432 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6433 * error anyway, so let's raise it. */
6434 if (!result)
6435 result = PyErr_SetFromWindowsErr(GetLastError());
6436
6437 CloseHandle(snapshot);
6438
6439 return result;
6440}
6441#endif /*MS_WINDOWS*/
6442
Larry Hastings2f936352014-08-05 14:04:04 +10006443
6444/*[clinic input]
6445os.getppid
6446
6447Return the parent's process id.
6448
6449If the parent process has already exited, Windows machines will still
6450return its id; others systems will return the id of the 'init' process (1).
6451[clinic start generated code]*/
6452
Larry Hastings2f936352014-08-05 14:04:04 +10006453static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006454os_getppid_impl(PyObject *module)
6455/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006456{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006457#ifdef MS_WINDOWS
6458 return win32_getppid();
6459#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006461#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006462}
6463#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006465
Fred Drake12c6e2d1999-12-14 21:25:03 +00006466#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006467/*[clinic input]
6468os.getlogin
6469
6470Return the actual login name.
6471[clinic start generated code]*/
6472
Larry Hastings2f936352014-08-05 14:04:04 +10006473static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006474os_getlogin_impl(PyObject *module)
6475/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006476{
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006478#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006479 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006480 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006481
6482 if (GetUserNameW(user_name, &num_chars)) {
6483 /* num_chars is the number of unicode chars plus null terminator */
6484 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006485 }
6486 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006487 result = PyErr_SetFromWindowsErr(GetLastError());
6488#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006489 char *name;
6490 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006491
Victor Stinner8c62be82010-05-06 00:08:46 +00006492 errno = 0;
6493 name = getlogin();
6494 if (name == NULL) {
6495 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006496 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006497 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006498 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006499 }
6500 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006501 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006502 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006503#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006504 return result;
6505}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006506#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006507
Larry Hastings2f936352014-08-05 14:04:04 +10006508
Guido van Rossumad0ee831995-03-01 10:34:45 +00006509#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006510/*[clinic input]
6511os.getuid
6512
6513Return the current process's user id.
6514[clinic start generated code]*/
6515
Larry Hastings2f936352014-08-05 14:04:04 +10006516static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006517os_getuid_impl(PyObject *module)
6518/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006519{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006520 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006521}
Larry Hastings2f936352014-08-05 14:04:04 +10006522#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006523
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006524
Brian Curtineb24d742010-04-12 17:16:38 +00006525#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006526#define HAVE_KILL
6527#endif /* MS_WINDOWS */
6528
6529#ifdef HAVE_KILL
6530/*[clinic input]
6531os.kill
6532
6533 pid: pid_t
6534 signal: Py_ssize_t
6535 /
6536
6537Kill a process with a signal.
6538[clinic start generated code]*/
6539
Larry Hastings2f936352014-08-05 14:04:04 +10006540static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006541os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6542/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006543#ifndef MS_WINDOWS
6544{
6545 if (kill(pid, (int)signal) == -1)
6546 return posix_error();
6547 Py_RETURN_NONE;
6548}
6549#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006550{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006551 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006552 DWORD sig = (DWORD)signal;
6553 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006555
Victor Stinner8c62be82010-05-06 00:08:46 +00006556 /* Console processes which share a common console can be sent CTRL+C or
6557 CTRL+BREAK events, provided they handle said events. */
6558 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006559 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 err = GetLastError();
6561 PyErr_SetFromWindowsErr(err);
6562 }
6563 else
6564 Py_RETURN_NONE;
6565 }
Brian Curtineb24d742010-04-12 17:16:38 +00006566
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6568 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006569 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 if (handle == NULL) {
6571 err = GetLastError();
6572 return PyErr_SetFromWindowsErr(err);
6573 }
Brian Curtineb24d742010-04-12 17:16:38 +00006574
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 if (TerminateProcess(handle, sig) == 0) {
6576 err = GetLastError();
6577 result = PyErr_SetFromWindowsErr(err);
6578 } else {
6579 Py_INCREF(Py_None);
6580 result = Py_None;
6581 }
Brian Curtineb24d742010-04-12 17:16:38 +00006582
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 CloseHandle(handle);
6584 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006585}
Larry Hastings2f936352014-08-05 14:04:04 +10006586#endif /* !MS_WINDOWS */
6587#endif /* HAVE_KILL */
6588
6589
6590#ifdef HAVE_KILLPG
6591/*[clinic input]
6592os.killpg
6593
6594 pgid: pid_t
6595 signal: int
6596 /
6597
6598Kill a process group with a signal.
6599[clinic start generated code]*/
6600
Larry Hastings2f936352014-08-05 14:04:04 +10006601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006602os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6603/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006604{
6605 /* XXX some man pages make the `pgid` parameter an int, others
6606 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6607 take the same type. Moreover, pid_t is always at least as wide as
6608 int (else compilation of this module fails), which is safe. */
6609 if (killpg(pgid, signal) == -1)
6610 return posix_error();
6611 Py_RETURN_NONE;
6612}
6613#endif /* HAVE_KILLPG */
6614
Brian Curtineb24d742010-04-12 17:16:38 +00006615
Guido van Rossumc0125471996-06-28 18:55:32 +00006616#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006617#ifdef HAVE_SYS_LOCK_H
6618#include <sys/lock.h>
6619#endif
6620
Larry Hastings2f936352014-08-05 14:04:04 +10006621/*[clinic input]
6622os.plock
6623 op: int
6624 /
6625
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006626Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006627[clinic start generated code]*/
6628
Larry Hastings2f936352014-08-05 14:04:04 +10006629static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006630os_plock_impl(PyObject *module, int op)
6631/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006632{
Victor Stinner8c62be82010-05-06 00:08:46 +00006633 if (plock(op) == -1)
6634 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006635 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006636}
Larry Hastings2f936352014-08-05 14:04:04 +10006637#endif /* HAVE_PLOCK */
6638
Guido van Rossumc0125471996-06-28 18:55:32 +00006639
Guido van Rossumb6775db1994-08-01 11:34:53 +00006640#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006641/*[clinic input]
6642os.setuid
6643
6644 uid: uid_t
6645 /
6646
6647Set the current process's user id.
6648[clinic start generated code]*/
6649
Larry Hastings2f936352014-08-05 14:04:04 +10006650static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006651os_setuid_impl(PyObject *module, uid_t uid)
6652/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006653{
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 if (setuid(uid) < 0)
6655 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006656 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006657}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006658#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006659
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006660
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006661#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006662/*[clinic input]
6663os.seteuid
6664
6665 euid: uid_t
6666 /
6667
6668Set the current process's effective user id.
6669[clinic start generated code]*/
6670
Larry Hastings2f936352014-08-05 14:04:04 +10006671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006672os_seteuid_impl(PyObject *module, uid_t euid)
6673/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006674{
6675 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006676 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006677 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006678}
6679#endif /* HAVE_SETEUID */
6680
Larry Hastings2f936352014-08-05 14:04:04 +10006681
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006682#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006683/*[clinic input]
6684os.setegid
6685
6686 egid: gid_t
6687 /
6688
6689Set the current process's effective group id.
6690[clinic start generated code]*/
6691
Larry Hastings2f936352014-08-05 14:04:04 +10006692static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006693os_setegid_impl(PyObject *module, gid_t egid)
6694/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006695{
6696 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006697 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006698 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006699}
6700#endif /* HAVE_SETEGID */
6701
Larry Hastings2f936352014-08-05 14:04:04 +10006702
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006703#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006704/*[clinic input]
6705os.setreuid
6706
6707 ruid: uid_t
6708 euid: uid_t
6709 /
6710
6711Set the current process's real and effective user ids.
6712[clinic start generated code]*/
6713
Larry Hastings2f936352014-08-05 14:04:04 +10006714static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006715os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6716/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006717{
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 if (setreuid(ruid, euid) < 0) {
6719 return posix_error();
6720 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006721 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006722 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006723}
6724#endif /* HAVE_SETREUID */
6725
Larry Hastings2f936352014-08-05 14:04:04 +10006726
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006727#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006728/*[clinic input]
6729os.setregid
6730
6731 rgid: gid_t
6732 egid: gid_t
6733 /
6734
6735Set the current process's real and effective group ids.
6736[clinic start generated code]*/
6737
Larry Hastings2f936352014-08-05 14:04:04 +10006738static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006739os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6740/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006741{
6742 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006743 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006744 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006745}
6746#endif /* HAVE_SETREGID */
6747
Larry Hastings2f936352014-08-05 14:04:04 +10006748
Guido van Rossumb6775db1994-08-01 11:34:53 +00006749#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006750/*[clinic input]
6751os.setgid
6752 gid: gid_t
6753 /
6754
6755Set the current process's group id.
6756[clinic start generated code]*/
6757
Larry Hastings2f936352014-08-05 14:04:04 +10006758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006759os_setgid_impl(PyObject *module, gid_t gid)
6760/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006761{
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 if (setgid(gid) < 0)
6763 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006764 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006765}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006766#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006767
Larry Hastings2f936352014-08-05 14:04:04 +10006768
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006769#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006770/*[clinic input]
6771os.setgroups
6772
6773 groups: object
6774 /
6775
6776Set the groups of the current process to list.
6777[clinic start generated code]*/
6778
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006779static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006780os_setgroups(PyObject *module, PyObject *groups)
6781/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006782{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006783 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006785
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 if (!PySequence_Check(groups)) {
6787 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6788 return NULL;
6789 }
6790 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006791 if (len < 0) {
6792 return NULL;
6793 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 if (len > MAX_GROUPS) {
6795 PyErr_SetString(PyExc_ValueError, "too many groups");
6796 return NULL;
6797 }
6798 for(i = 0; i < len; i++) {
6799 PyObject *elem;
6800 elem = PySequence_GetItem(groups, i);
6801 if (!elem)
6802 return NULL;
6803 if (!PyLong_Check(elem)) {
6804 PyErr_SetString(PyExc_TypeError,
6805 "groups must be integers");
6806 Py_DECREF(elem);
6807 return NULL;
6808 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006809 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006810 Py_DECREF(elem);
6811 return NULL;
6812 }
6813 }
6814 Py_DECREF(elem);
6815 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006816
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 if (setgroups(len, grouplist) < 0)
6818 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006819 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006820}
6821#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006822
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006823#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6824static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006825wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006826{
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 PyObject *result;
6828 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006829 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006830
Victor Stinner8c62be82010-05-06 00:08:46 +00006831 if (pid == -1)
6832 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006833
Victor Stinner8c62be82010-05-06 00:08:46 +00006834 if (struct_rusage == NULL) {
6835 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6836 if (m == NULL)
6837 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006838 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 Py_DECREF(m);
6840 if (struct_rusage == NULL)
6841 return NULL;
6842 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006843
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6845 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6846 if (!result)
6847 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006848
6849#ifndef doubletime
6850#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6851#endif
6852
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006854 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006855 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006856 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006857#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006858 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6859 SET_INT(result, 2, ru->ru_maxrss);
6860 SET_INT(result, 3, ru->ru_ixrss);
6861 SET_INT(result, 4, ru->ru_idrss);
6862 SET_INT(result, 5, ru->ru_isrss);
6863 SET_INT(result, 6, ru->ru_minflt);
6864 SET_INT(result, 7, ru->ru_majflt);
6865 SET_INT(result, 8, ru->ru_nswap);
6866 SET_INT(result, 9, ru->ru_inblock);
6867 SET_INT(result, 10, ru->ru_oublock);
6868 SET_INT(result, 11, ru->ru_msgsnd);
6869 SET_INT(result, 12, ru->ru_msgrcv);
6870 SET_INT(result, 13, ru->ru_nsignals);
6871 SET_INT(result, 14, ru->ru_nvcsw);
6872 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006873#undef SET_INT
6874
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 if (PyErr_Occurred()) {
6876 Py_DECREF(result);
6877 return NULL;
6878 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006879
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006881}
6882#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6883
Larry Hastings2f936352014-08-05 14:04:04 +10006884
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006885#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006886/*[clinic input]
6887os.wait3
6888
6889 options: int
6890Wait for completion of a child process.
6891
6892Returns a tuple of information about the child process:
6893 (pid, status, rusage)
6894[clinic start generated code]*/
6895
Larry Hastings2f936352014-08-05 14:04:04 +10006896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006897os_wait3_impl(PyObject *module, int options)
6898/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006899{
Victor Stinner8c62be82010-05-06 00:08:46 +00006900 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006902 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006903 WAIT_TYPE status;
6904 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006905
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006906 do {
6907 Py_BEGIN_ALLOW_THREADS
6908 pid = wait3(&status, options, &ru);
6909 Py_END_ALLOW_THREADS
6910 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6911 if (pid < 0)
6912 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006913
Victor Stinner4195b5c2012-02-08 23:03:19 +01006914 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006915}
6916#endif /* HAVE_WAIT3 */
6917
Larry Hastings2f936352014-08-05 14:04:04 +10006918
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006919#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006920/*[clinic input]
6921
6922os.wait4
6923
6924 pid: pid_t
6925 options: int
6926
6927Wait for completion of a specific child process.
6928
6929Returns a tuple of information about the child process:
6930 (pid, status, rusage)
6931[clinic start generated code]*/
6932
Larry Hastings2f936352014-08-05 14:04:04 +10006933static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006934os_wait4_impl(PyObject *module, pid_t pid, int options)
6935/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006936{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006937 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006939 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 WAIT_TYPE status;
6941 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006942
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006943 do {
6944 Py_BEGIN_ALLOW_THREADS
6945 res = wait4(pid, &status, options, &ru);
6946 Py_END_ALLOW_THREADS
6947 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6948 if (res < 0)
6949 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006950
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006951 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006952}
6953#endif /* HAVE_WAIT4 */
6954
Larry Hastings2f936352014-08-05 14:04:04 +10006955
Ross Lagerwall7807c352011-03-17 20:20:30 +02006956#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006957/*[clinic input]
6958os.waitid
6959
6960 idtype: idtype_t
6961 Must be one of be P_PID, P_PGID or P_ALL.
6962 id: id_t
6963 The id to wait on.
6964 options: int
6965 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6966 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6967 /
6968
6969Returns the result of waiting for a process or processes.
6970
6971Returns either waitid_result or None if WNOHANG is specified and there are
6972no children in a waitable state.
6973[clinic start generated code]*/
6974
Larry Hastings2f936352014-08-05 14:04:04 +10006975static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006976os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6977/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006978{
6979 PyObject *result;
6980 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006981 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006982 siginfo_t si;
6983 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006984
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006985 do {
6986 Py_BEGIN_ALLOW_THREADS
6987 res = waitid(idtype, id, &si, options);
6988 Py_END_ALLOW_THREADS
6989 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6990 if (res < 0)
6991 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006992
6993 if (si.si_pid == 0)
6994 Py_RETURN_NONE;
6995
6996 result = PyStructSequence_New(&WaitidResultType);
6997 if (!result)
6998 return NULL;
6999
7000 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007001 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007002 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7003 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7004 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7005 if (PyErr_Occurred()) {
7006 Py_DECREF(result);
7007 return NULL;
7008 }
7009
7010 return result;
7011}
Larry Hastings2f936352014-08-05 14:04:04 +10007012#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007013
Larry Hastings2f936352014-08-05 14:04:04 +10007014
7015#if defined(HAVE_WAITPID)
7016/*[clinic input]
7017os.waitpid
7018 pid: pid_t
7019 options: int
7020 /
7021
7022Wait for completion of a given child process.
7023
7024Returns a tuple of information regarding the child process:
7025 (pid, status)
7026
7027The options argument is ignored on Windows.
7028[clinic start generated code]*/
7029
Larry Hastings2f936352014-08-05 14:04:04 +10007030static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007031os_waitpid_impl(PyObject *module, pid_t pid, int options)
7032/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007033{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007034 pid_t res;
7035 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 WAIT_TYPE status;
7037 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007038
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007039 do {
7040 Py_BEGIN_ALLOW_THREADS
7041 res = waitpid(pid, &status, options);
7042 Py_END_ALLOW_THREADS
7043 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7044 if (res < 0)
7045 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007046
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007047 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007048}
Tim Petersab034fa2002-02-01 11:27:43 +00007049#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007050/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007051/*[clinic input]
7052os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007053 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007054 options: int
7055 /
7056
7057Wait for completion of a given process.
7058
7059Returns a tuple of information regarding the process:
7060 (pid, status << 8)
7061
7062The options argument is ignored on Windows.
7063[clinic start generated code]*/
7064
Larry Hastings2f936352014-08-05 14:04:04 +10007065static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007066os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007067/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007068{
7069 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007070 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007071 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007072
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007073 do {
7074 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007075 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007076 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007077 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007078 Py_END_ALLOW_THREADS
7079 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007080 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007081 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007082
Victor Stinner8c62be82010-05-06 00:08:46 +00007083 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007084 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007085}
Larry Hastings2f936352014-08-05 14:04:04 +10007086#endif
7087
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007088
Guido van Rossumad0ee831995-03-01 10:34:45 +00007089#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007090/*[clinic input]
7091os.wait
7092
7093Wait for completion of a child process.
7094
7095Returns a tuple of information about the child process:
7096 (pid, status)
7097[clinic start generated code]*/
7098
Larry Hastings2f936352014-08-05 14:04:04 +10007099static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007100os_wait_impl(PyObject *module)
7101/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007102{
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007104 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 WAIT_TYPE status;
7106 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007107
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007108 do {
7109 Py_BEGIN_ALLOW_THREADS
7110 pid = wait(&status);
7111 Py_END_ALLOW_THREADS
7112 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7113 if (pid < 0)
7114 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007115
Victor Stinner8c62be82010-05-06 00:08:46 +00007116 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007117}
Larry Hastings2f936352014-08-05 14:04:04 +10007118#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007120
Larry Hastings9cf065c2012-06-22 16:30:09 -07007121#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7122PyDoc_STRVAR(readlink__doc__,
7123"readlink(path, *, dir_fd=None) -> path\n\n\
7124Return a string representing the path to which the symbolic link points.\n\
7125\n\
7126If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7127 and path should be relative; path will then be relative to that directory.\n\
7128dir_fd may not be implemented on your platform.\n\
7129 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007130#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007131
Guido van Rossumb6775db1994-08-01 11:34:53 +00007132#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007133
Larry Hastings2f936352014-08-05 14:04:04 +10007134/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007135static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007136posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007137{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007138 path_t path;
7139 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007140 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007141 ssize_t length;
7142 PyObject *return_value = NULL;
7143 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007144
Larry Hastings9cf065c2012-06-22 16:30:09 -07007145 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007146 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007147 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7148 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007149 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007151
Victor Stinner8c62be82010-05-06 00:08:46 +00007152 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007153#ifdef HAVE_READLINKAT
7154 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007155 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007156 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007157#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007158 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007159 Py_END_ALLOW_THREADS
7160
7161 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007162 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007163 goto exit;
7164 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007165 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007166
7167 if (PyUnicode_Check(path.object))
7168 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7169 else
7170 return_value = PyBytes_FromStringAndSize(buffer, length);
7171exit:
7172 path_cleanup(&path);
7173 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007174}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007175
Guido van Rossumb6775db1994-08-01 11:34:53 +00007176#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007177
Larry Hastings2f936352014-08-05 14:04:04 +10007178#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7179
7180static PyObject *
7181win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7182{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007183 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007184 DWORD n_bytes_returned;
7185 DWORD io_result;
7186 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007187 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007188 HANDLE reparse_point_handle;
7189
Martin Panter70214ad2016-08-04 02:38:59 +00007190 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7191 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007192 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007193
7194 static char *keywords[] = {"path", "dir_fd", NULL};
7195
7196 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7197 &po,
7198 dir_fd_unavailable, &dir_fd
7199 ))
7200 return NULL;
7201
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007202 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007203 if (path == NULL)
7204 return NULL;
7205
7206 /* First get a handle to the reparse point */
7207 Py_BEGIN_ALLOW_THREADS
7208 reparse_point_handle = CreateFileW(
7209 path,
7210 0,
7211 0,
7212 0,
7213 OPEN_EXISTING,
7214 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7215 0);
7216 Py_END_ALLOW_THREADS
7217
7218 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7219 return win32_error_object("readlink", po);
7220
7221 Py_BEGIN_ALLOW_THREADS
7222 /* New call DeviceIoControl to read the reparse point */
7223 io_result = DeviceIoControl(
7224 reparse_point_handle,
7225 FSCTL_GET_REPARSE_POINT,
7226 0, 0, /* in buffer */
7227 target_buffer, sizeof(target_buffer),
7228 &n_bytes_returned,
7229 0 /* we're not using OVERLAPPED_IO */
7230 );
7231 CloseHandle(reparse_point_handle);
7232 Py_END_ALLOW_THREADS
7233
7234 if (io_result==0)
7235 return win32_error_object("readlink", po);
7236
7237 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7238 {
7239 PyErr_SetString(PyExc_ValueError,
7240 "not a symbolic link");
7241 return NULL;
7242 }
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007243 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7244 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007245
7246 result = PyUnicode_FromWideChar(print_name,
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007247 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
Larry Hastings2f936352014-08-05 14:04:04 +10007248 return result;
7249}
7250
7251#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7252
7253
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007254
Larry Hastings9cf065c2012-06-22 16:30:09 -07007255#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007256
7257#if defined(MS_WINDOWS)
7258
7259/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007260static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007261
Larry Hastings9cf065c2012-06-22 16:30:09 -07007262static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007263check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007264{
7265 HINSTANCE hKernel32;
7266 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007267 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007268 return 1;
7269 hKernel32 = GetModuleHandleW(L"KERNEL32");
7270 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7271 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007272 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007273}
7274
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007275/* Remove the last portion of the path - return 0 on success */
7276static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007277_dirnameW(WCHAR *path)
7278{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007279 WCHAR *ptr;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007280 size_t length = wcsnlen_s(path, MAX_PATH);
7281 if (length == MAX_PATH) {
7282 return -1;
7283 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007284
7285 /* walk the path from the end until a backslash is encountered */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007286 for(ptr = path + length; ptr != path; ptr--) {
7287 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007288 break;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007289 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007290 }
7291 *ptr = 0;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007292 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007293}
7294
Victor Stinner31b3b922013-06-05 01:49:17 +02007295/* Is this path absolute? */
7296static int
7297_is_absW(const WCHAR *path)
7298{
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007299 return path[0] == L'\\' || path[0] == L'/' ||
7300 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007301}
7302
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007303/* join root and rest with a backslash - return 0 on success */
7304static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007305_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7306{
Victor Stinner31b3b922013-06-05 01:49:17 +02007307 if (_is_absW(rest)) {
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007308 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007309 }
7310
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007311 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7312 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007313 }
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007314
7315 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7316 return -1;
7317 }
7318
7319 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007320}
7321
Victor Stinner31b3b922013-06-05 01:49:17 +02007322/* Return True if the path at src relative to dest is a directory */
7323static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007324_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007325{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007326 WIN32_FILE_ATTRIBUTE_DATA src_info;
7327 WCHAR dest_parent[MAX_PATH];
7328 WCHAR src_resolved[MAX_PATH] = L"";
7329
7330 /* dest_parent = os.path.dirname(dest) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007331 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7332 _dirnameW(dest_parent)) {
7333 return 0;
7334 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007335 /* src_resolved = os.path.join(dest_parent, src) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007336 if (_joinW(src_resolved, dest_parent, src)) {
7337 return 0;
7338 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007339 return (
7340 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7341 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7342 );
7343}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007344#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007345
Larry Hastings2f936352014-08-05 14:04:04 +10007346
7347/*[clinic input]
7348os.symlink
7349 src: path_t
7350 dst: path_t
7351 target_is_directory: bool = False
7352 *
7353 dir_fd: dir_fd(requires='symlinkat')=None
7354
7355# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7356
7357Create a symbolic link pointing to src named dst.
7358
7359target_is_directory is required on Windows if the target is to be
7360 interpreted as a directory. (On Windows, symlink requires
7361 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7362 target_is_directory is ignored on non-Windows platforms.
7363
7364If dir_fd is not None, it should be a file descriptor open to a directory,
7365 and path should be relative; path will then be relative to that directory.
7366dir_fd may not be implemented on your platform.
7367 If it is unavailable, using it will raise a NotImplementedError.
7368
7369[clinic start generated code]*/
7370
Larry Hastings2f936352014-08-05 14:04:04 +10007371static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007372os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007373 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007374/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007375{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007376#ifdef MS_WINDOWS
7377 DWORD result;
7378#else
7379 int result;
7380#endif
7381
Larry Hastings9cf065c2012-06-22 16:30:09 -07007382#ifdef MS_WINDOWS
7383 if (!check_CreateSymbolicLink()) {
7384 PyErr_SetString(PyExc_NotImplementedError,
7385 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007386 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007387 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007388 if (!win32_can_symlink) {
7389 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007390 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007391 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007392#endif
7393
Larry Hastings9cf065c2012-06-22 16:30:09 -07007394#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007395
Larry Hastings9cf065c2012-06-22 16:30:09 -07007396 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007397 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007398 /* if src is a directory, ensure target_is_directory==1 */
7399 target_is_directory |= _check_dirW(src->wide, dst->wide);
7400 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7401 target_is_directory);
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007402 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007403 Py_END_ALLOW_THREADS
7404
Larry Hastings2f936352014-08-05 14:04:04 +10007405 if (!result)
7406 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007407
7408#else
7409
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007410 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7411 PyErr_SetString(PyExc_ValueError,
7412 "symlink: src and dst must be the same type");
7413 return NULL;
7414 }
7415
Larry Hastings9cf065c2012-06-22 16:30:09 -07007416 Py_BEGIN_ALLOW_THREADS
7417#if HAVE_SYMLINKAT
7418 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007419 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007420 else
7421#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007422 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007423 Py_END_ALLOW_THREADS
7424
Larry Hastings2f936352014-08-05 14:04:04 +10007425 if (result)
7426 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007427#endif
7428
Larry Hastings2f936352014-08-05 14:04:04 +10007429 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007430}
7431#endif /* HAVE_SYMLINK */
7432
Larry Hastings9cf065c2012-06-22 16:30:09 -07007433
Brian Curtind40e6f72010-07-08 21:39:08 +00007434
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007435
Larry Hastings605a62d2012-06-24 04:33:36 -07007436static PyStructSequence_Field times_result_fields[] = {
7437 {"user", "user time"},
7438 {"system", "system time"},
7439 {"children_user", "user time of children"},
7440 {"children_system", "system time of children"},
7441 {"elapsed", "elapsed time since an arbitrary point in the past"},
7442 {NULL}
7443};
7444
7445PyDoc_STRVAR(times_result__doc__,
7446"times_result: Result from os.times().\n\n\
7447This object may be accessed either as a tuple of\n\
7448 (user, system, children_user, children_system, elapsed),\n\
7449or via the attributes user, system, children_user, children_system,\n\
7450and elapsed.\n\
7451\n\
7452See os.times for more information.");
7453
7454static PyStructSequence_Desc times_result_desc = {
7455 "times_result", /* name */
7456 times_result__doc__, /* doc */
7457 times_result_fields,
7458 5
7459};
7460
7461static PyTypeObject TimesResultType;
7462
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007463#ifdef MS_WINDOWS
7464#define HAVE_TIMES /* mandatory, for the method table */
7465#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007466
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007467#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007468
7469static PyObject *
7470build_times_result(double user, double system,
7471 double children_user, double children_system,
7472 double elapsed)
7473{
7474 PyObject *value = PyStructSequence_New(&TimesResultType);
7475 if (value == NULL)
7476 return NULL;
7477
7478#define SET(i, field) \
7479 { \
7480 PyObject *o = PyFloat_FromDouble(field); \
7481 if (!o) { \
7482 Py_DECREF(value); \
7483 return NULL; \
7484 } \
7485 PyStructSequence_SET_ITEM(value, i, o); \
7486 } \
7487
7488 SET(0, user);
7489 SET(1, system);
7490 SET(2, children_user);
7491 SET(3, children_system);
7492 SET(4, elapsed);
7493
7494#undef SET
7495
7496 return value;
7497}
7498
Larry Hastings605a62d2012-06-24 04:33:36 -07007499
Larry Hastings2f936352014-08-05 14:04:04 +10007500#ifndef MS_WINDOWS
7501#define NEED_TICKS_PER_SECOND
7502static long ticks_per_second = -1;
7503#endif /* MS_WINDOWS */
7504
7505/*[clinic input]
7506os.times
7507
7508Return a collection containing process timing information.
7509
7510The object returned behaves like a named tuple with these fields:
7511 (utime, stime, cutime, cstime, elapsed_time)
7512All fields are floating point numbers.
7513[clinic start generated code]*/
7514
Larry Hastings2f936352014-08-05 14:04:04 +10007515static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007516os_times_impl(PyObject *module)
7517/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007518#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007519{
Victor Stinner8c62be82010-05-06 00:08:46 +00007520 FILETIME create, exit, kernel, user;
7521 HANDLE hProc;
7522 hProc = GetCurrentProcess();
7523 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7524 /* The fields of a FILETIME structure are the hi and lo part
7525 of a 64-bit value expressed in 100 nanosecond units.
7526 1e7 is one second in such units; 1e-7 the inverse.
7527 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7528 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007529 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007530 (double)(user.dwHighDateTime*429.4967296 +
7531 user.dwLowDateTime*1e-7),
7532 (double)(kernel.dwHighDateTime*429.4967296 +
7533 kernel.dwLowDateTime*1e-7),
7534 (double)0,
7535 (double)0,
7536 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007537}
Larry Hastings2f936352014-08-05 14:04:04 +10007538#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007539{
Larry Hastings2f936352014-08-05 14:04:04 +10007540
7541
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007542 struct tms t;
7543 clock_t c;
7544 errno = 0;
7545 c = times(&t);
7546 if (c == (clock_t) -1)
7547 return posix_error();
7548 return build_times_result(
7549 (double)t.tms_utime / ticks_per_second,
7550 (double)t.tms_stime / ticks_per_second,
7551 (double)t.tms_cutime / ticks_per_second,
7552 (double)t.tms_cstime / ticks_per_second,
7553 (double)c / ticks_per_second);
7554}
Larry Hastings2f936352014-08-05 14:04:04 +10007555#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007556#endif /* HAVE_TIMES */
7557
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007558
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007559#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007560/*[clinic input]
7561os.getsid
7562
7563 pid: pid_t
7564 /
7565
7566Call the system call getsid(pid) and return the result.
7567[clinic start generated code]*/
7568
Larry Hastings2f936352014-08-05 14:04:04 +10007569static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007570os_getsid_impl(PyObject *module, pid_t pid)
7571/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007572{
Victor Stinner8c62be82010-05-06 00:08:46 +00007573 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007574 sid = getsid(pid);
7575 if (sid < 0)
7576 return posix_error();
7577 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007578}
7579#endif /* HAVE_GETSID */
7580
7581
Guido van Rossumb6775db1994-08-01 11:34:53 +00007582#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007583/*[clinic input]
7584os.setsid
7585
7586Call the system call setsid().
7587[clinic start generated code]*/
7588
Larry Hastings2f936352014-08-05 14:04:04 +10007589static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007590os_setsid_impl(PyObject *module)
7591/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007592{
Victor Stinner8c62be82010-05-06 00:08:46 +00007593 if (setsid() < 0)
7594 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007595 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007596}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007597#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007598
Larry Hastings2f936352014-08-05 14:04:04 +10007599
Guido van Rossumb6775db1994-08-01 11:34:53 +00007600#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007601/*[clinic input]
7602os.setpgid
7603
7604 pid: pid_t
7605 pgrp: pid_t
7606 /
7607
7608Call the system call setpgid(pid, pgrp).
7609[clinic start generated code]*/
7610
Larry Hastings2f936352014-08-05 14:04:04 +10007611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007612os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7613/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007614{
Victor Stinner8c62be82010-05-06 00:08:46 +00007615 if (setpgid(pid, pgrp) < 0)
7616 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007617 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007618}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007619#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007620
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007621
Guido van Rossumb6775db1994-08-01 11:34:53 +00007622#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007623/*[clinic input]
7624os.tcgetpgrp
7625
7626 fd: int
7627 /
7628
7629Return the process group associated with the terminal specified by fd.
7630[clinic start generated code]*/
7631
Larry Hastings2f936352014-08-05 14:04:04 +10007632static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007633os_tcgetpgrp_impl(PyObject *module, int fd)
7634/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007635{
7636 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007637 if (pgid < 0)
7638 return posix_error();
7639 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007640}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007641#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007642
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007643
Guido van Rossumb6775db1994-08-01 11:34:53 +00007644#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007645/*[clinic input]
7646os.tcsetpgrp
7647
7648 fd: int
7649 pgid: pid_t
7650 /
7651
7652Set the process group associated with the terminal specified by fd.
7653[clinic start generated code]*/
7654
Larry Hastings2f936352014-08-05 14:04:04 +10007655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007656os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7657/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007658{
Victor Stinner8c62be82010-05-06 00:08:46 +00007659 if (tcsetpgrp(fd, pgid) < 0)
7660 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007661 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007662}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007663#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007664
Guido van Rossum687dd131993-05-17 08:34:16 +00007665/* Functions acting on file descriptors */
7666
Victor Stinnerdaf45552013-08-28 00:53:59 +02007667#ifdef O_CLOEXEC
7668extern int _Py_open_cloexec_works;
7669#endif
7670
Larry Hastings2f936352014-08-05 14:04:04 +10007671
7672/*[clinic input]
7673os.open -> int
7674 path: path_t
7675 flags: int
7676 mode: int = 0o777
7677 *
7678 dir_fd: dir_fd(requires='openat') = None
7679
7680# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7681
7682Open a file for low level IO. Returns a file descriptor (integer).
7683
7684If dir_fd is not None, it should be a file descriptor open to a directory,
7685 and path should be relative; path will then be relative to that directory.
7686dir_fd may not be implemented on your platform.
7687 If it is unavailable, using it will raise a NotImplementedError.
7688[clinic start generated code]*/
7689
Larry Hastings2f936352014-08-05 14:04:04 +10007690static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007691os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7692/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007693{
7694 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007695 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007696
Victor Stinnerdaf45552013-08-28 00:53:59 +02007697#ifdef O_CLOEXEC
7698 int *atomic_flag_works = &_Py_open_cloexec_works;
7699#elif !defined(MS_WINDOWS)
7700 int *atomic_flag_works = NULL;
7701#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007702
Victor Stinnerdaf45552013-08-28 00:53:59 +02007703#ifdef MS_WINDOWS
7704 flags |= O_NOINHERIT;
7705#elif defined(O_CLOEXEC)
7706 flags |= O_CLOEXEC;
7707#endif
7708
Steve Dower8fc89802015-04-12 00:26:27 -04007709 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007710 do {
7711 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007712#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007713 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007714#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007715#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007716 if (dir_fd != DEFAULT_DIR_FD)
7717 fd = openat(dir_fd, path->narrow, flags, mode);
7718 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007719#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007720 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007721#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007722 Py_END_ALLOW_THREADS
7723 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007724 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007725
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007726 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007727 if (!async_err)
7728 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007729 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007730 }
7731
Victor Stinnerdaf45552013-08-28 00:53:59 +02007732#ifndef MS_WINDOWS
7733 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7734 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007735 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007736 }
7737#endif
7738
Larry Hastings2f936352014-08-05 14:04:04 +10007739 return fd;
7740}
7741
7742
7743/*[clinic input]
7744os.close
7745
7746 fd: int
7747
7748Close a file descriptor.
7749[clinic start generated code]*/
7750
Barry Warsaw53699e91996-12-10 23:23:01 +00007751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007752os_close_impl(PyObject *module, int fd)
7753/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007754{
Larry Hastings2f936352014-08-05 14:04:04 +10007755 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007756 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7757 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7758 * for more details.
7759 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007760 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007761 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007762 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007763 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007764 Py_END_ALLOW_THREADS
7765 if (res < 0)
7766 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007767 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007768}
7769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007770
Larry Hastings2f936352014-08-05 14:04:04 +10007771/*[clinic input]
7772os.closerange
7773
7774 fd_low: int
7775 fd_high: int
7776 /
7777
7778Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7779[clinic start generated code]*/
7780
Larry Hastings2f936352014-08-05 14:04:04 +10007781static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007782os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7783/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007784{
7785 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007787 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007788 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007789 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007790 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 Py_END_ALLOW_THREADS
7792 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007793}
7794
7795
Larry Hastings2f936352014-08-05 14:04:04 +10007796/*[clinic input]
7797os.dup -> int
7798
7799 fd: int
7800 /
7801
7802Return a duplicate of a file descriptor.
7803[clinic start generated code]*/
7804
Larry Hastings2f936352014-08-05 14:04:04 +10007805static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007806os_dup_impl(PyObject *module, int fd)
7807/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007808{
7809 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007810}
7811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007812
Larry Hastings2f936352014-08-05 14:04:04 +10007813/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007814os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10007815 fd: int
7816 fd2: int
7817 inheritable: bool=True
7818
7819Duplicate file descriptor.
7820[clinic start generated code]*/
7821
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007822static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007823os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007824/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007825{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01007826 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007827#if defined(HAVE_DUP3) && \
7828 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7829 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Miss Islington (bot)bab4fe32018-02-19 23:46:47 -08007830 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007831#endif
7832
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007833 if (fd < 0 || fd2 < 0) {
7834 posix_error();
7835 return -1;
7836 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007837
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007838 /* dup2() can fail with EINTR if the target FD is already open, because it
7839 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7840 * upon close(), and therefore below.
7841 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007842#ifdef MS_WINDOWS
7843 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007844 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007845 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007846 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007847 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007848 if (res < 0) {
7849 posix_error();
7850 return -1;
7851 }
7852 res = fd2; // msvcrt dup2 returns 0 on success.
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);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007857 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007858 }
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
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007867 if (res < 0) {
7868 posix_error();
7869 return -1;
7870 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007871
7872#else
7873
7874#ifdef HAVE_DUP3
7875 if (!inheritable && dup3_works != 0) {
7876 Py_BEGIN_ALLOW_THREADS
7877 res = dup3(fd, fd2, O_CLOEXEC);
7878 Py_END_ALLOW_THREADS
7879 if (res < 0) {
7880 if (dup3_works == -1)
7881 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007882 if (dup3_works) {
7883 posix_error();
7884 return -1;
7885 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007886 }
7887 }
7888
7889 if (inheritable || dup3_works == 0)
7890 {
7891#endif
7892 Py_BEGIN_ALLOW_THREADS
7893 res = dup2(fd, fd2);
7894 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007895 if (res < 0) {
7896 posix_error();
7897 return -1;
7898 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007899
7900 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7901 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007902 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007903 }
7904#ifdef HAVE_DUP3
7905 }
7906#endif
7907
7908#endif
7909
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007910 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00007911}
7912
Larry Hastings2f936352014-08-05 14:04:04 +10007913
Ross Lagerwall7807c352011-03-17 20:20:30 +02007914#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007915/*[clinic input]
7916os.lockf
7917
7918 fd: int
7919 An open file descriptor.
7920 command: int
7921 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7922 length: Py_off_t
7923 The number of bytes to lock, starting at the current position.
7924 /
7925
7926Apply, test or remove a POSIX lock on an open file descriptor.
7927
7928[clinic start generated code]*/
7929
Larry Hastings2f936352014-08-05 14:04:04 +10007930static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007931os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7932/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007933{
7934 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007935
7936 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007937 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007938 Py_END_ALLOW_THREADS
7939
7940 if (res < 0)
7941 return posix_error();
7942
7943 Py_RETURN_NONE;
7944}
Larry Hastings2f936352014-08-05 14:04:04 +10007945#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007947
Larry Hastings2f936352014-08-05 14:04:04 +10007948/*[clinic input]
7949os.lseek -> Py_off_t
7950
7951 fd: int
7952 position: Py_off_t
7953 how: int
7954 /
7955
7956Set the position of a file descriptor. Return the new position.
7957
7958Return the new cursor position in number of bytes
7959relative to the beginning of the file.
7960[clinic start generated code]*/
7961
Larry Hastings2f936352014-08-05 14:04:04 +10007962static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007963os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7964/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007965{
7966 Py_off_t result;
7967
Guido van Rossum687dd131993-05-17 08:34:16 +00007968#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7970 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007971 case 0: how = SEEK_SET; break;
7972 case 1: how = SEEK_CUR; break;
7973 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007974 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007975#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007976
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007978 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007979
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007981 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007982#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007983 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007984#else
Larry Hastings2f936352014-08-05 14:04:04 +10007985 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007986#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007987 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007989 if (result < 0)
7990 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007991
Larry Hastings2f936352014-08-05 14:04:04 +10007992 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007993}
7994
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007995
Larry Hastings2f936352014-08-05 14:04:04 +10007996/*[clinic input]
7997os.read
7998 fd: int
7999 length: Py_ssize_t
8000 /
8001
8002Read from a file descriptor. Returns a bytes object.
8003[clinic start generated code]*/
8004
Larry Hastings2f936352014-08-05 14:04:04 +10008005static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008006os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8007/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008008{
Victor Stinner8c62be82010-05-06 00:08:46 +00008009 Py_ssize_t n;
8010 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008011
8012 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008013 errno = EINVAL;
8014 return posix_error();
8015 }
Larry Hastings2f936352014-08-05 14:04:04 +10008016
Miss Islington (bot)18f33272018-11-22 06:17:34 -08008017 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008018
8019 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008020 if (buffer == NULL)
8021 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008022
Victor Stinner66aab0c2015-03-19 22:53:20 +01008023 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8024 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008026 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008027 }
Larry Hastings2f936352014-08-05 14:04:04 +10008028
8029 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008031
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008033}
8034
Ross Lagerwall7807c352011-03-17 20:20:30 +02008035#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008036 || defined(__APPLE__))) \
8037 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8038 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8039static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008040iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008041{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008042 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008043
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008044 *iov = PyMem_New(struct iovec, cnt);
8045 if (*iov == NULL) {
8046 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008047 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008048 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008049
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008050 *buf = PyMem_New(Py_buffer, cnt);
8051 if (*buf == NULL) {
8052 PyMem_Del(*iov);
8053 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008054 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008055 }
8056
8057 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008058 PyObject *item = PySequence_GetItem(seq, i);
8059 if (item == NULL)
8060 goto fail;
8061 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8062 Py_DECREF(item);
8063 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008064 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008065 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066 (*iov)[i].iov_base = (*buf)[i].buf;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008067 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008068 }
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008069 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008070
8071fail:
8072 PyMem_Del(*iov);
8073 for (j = 0; j < i; j++) {
8074 PyBuffer_Release(&(*buf)[j]);
8075 }
8076 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008077 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008078}
8079
8080static void
8081iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8082{
8083 int i;
8084 PyMem_Del(iov);
8085 for (i = 0; i < cnt; i++) {
8086 PyBuffer_Release(&buf[i]);
8087 }
8088 PyMem_Del(buf);
8089}
8090#endif
8091
Larry Hastings2f936352014-08-05 14:04:04 +10008092
Ross Lagerwall7807c352011-03-17 20:20:30 +02008093#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008094/*[clinic input]
8095os.readv -> Py_ssize_t
8096
8097 fd: int
8098 buffers: object
8099 /
8100
8101Read from a file descriptor fd into an iterable of buffers.
8102
8103The buffers should be mutable buffers accepting bytes.
8104readv will transfer data into each buffer until it is full
8105and then move on to the next buffer in the sequence to hold
8106the rest of the data.
8107
8108readv returns the total number of bytes read,
8109which may be less than the total capacity of all the buffers.
8110[clinic start generated code]*/
8111
Larry Hastings2f936352014-08-05 14:04:04 +10008112static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008113os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8114/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008115{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008116 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008117 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008118 struct iovec *iov;
8119 Py_buffer *buf;
8120
Larry Hastings2f936352014-08-05 14:04:04 +10008121 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008122 PyErr_SetString(PyExc_TypeError,
8123 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008124 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008125 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008126
Larry Hastings2f936352014-08-05 14:04:04 +10008127 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008128 if (cnt < 0)
8129 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008130
8131 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8132 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008133
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008134 do {
8135 Py_BEGIN_ALLOW_THREADS
8136 n = readv(fd, iov, cnt);
8137 Py_END_ALLOW_THREADS
8138 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008139
8140 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008141 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008142 if (!async_err)
8143 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008144 return -1;
8145 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008146
Larry Hastings2f936352014-08-05 14:04:04 +10008147 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008148}
Larry Hastings2f936352014-08-05 14:04:04 +10008149#endif /* HAVE_READV */
8150
Ross Lagerwall7807c352011-03-17 20:20:30 +02008151
8152#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008153/*[clinic input]
8154# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8155os.pread
8156
8157 fd: int
8158 length: int
8159 offset: Py_off_t
8160 /
8161
8162Read a number of bytes from a file descriptor starting at a particular offset.
8163
8164Read length bytes from file descriptor fd, starting at offset bytes from
8165the beginning of the file. The file offset remains unchanged.
8166[clinic start generated code]*/
8167
Larry Hastings2f936352014-08-05 14:04:04 +10008168static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008169os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8170/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008171{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008172 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008173 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008174 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008175
Larry Hastings2f936352014-08-05 14:04:04 +10008176 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008177 errno = EINVAL;
8178 return posix_error();
8179 }
Larry Hastings2f936352014-08-05 14:04:04 +10008180 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008181 if (buffer == NULL)
8182 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008183
8184 do {
8185 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008186 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008187 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008188 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008189 Py_END_ALLOW_THREADS
8190 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8191
Ross Lagerwall7807c352011-03-17 20:20:30 +02008192 if (n < 0) {
8193 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008194 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008195 }
Larry Hastings2f936352014-08-05 14:04:04 +10008196 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008197 _PyBytes_Resize(&buffer, n);
8198 return buffer;
8199}
Larry Hastings2f936352014-08-05 14:04:04 +10008200#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008201
Pablo Galindo4defba32018-01-27 16:16:37 +00008202#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8203/*[clinic input]
8204os.preadv -> Py_ssize_t
8205
8206 fd: int
8207 buffers: object
8208 offset: Py_off_t
8209 flags: int = 0
8210 /
8211
8212Reads from a file descriptor into a number of mutable bytes-like objects.
8213
8214Combines the functionality of readv() and pread(). As readv(), it will
8215transfer data into each buffer until it is full and then move on to the next
8216buffer in the sequence to hold the rest of the data. Its fourth argument,
8217specifies the file offset at which the input operation is to be performed. It
8218will return the total number of bytes read (which can be less than the total
8219capacity of all the objects).
8220
8221The flags argument contains a bitwise OR of zero or more of the following flags:
8222
8223- RWF_HIPRI
8224- RWF_NOWAIT
8225
8226Using non-zero flags requires Linux 4.6 or newer.
8227[clinic start generated code]*/
8228
8229static Py_ssize_t
8230os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8231 int flags)
8232/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8233{
8234 Py_ssize_t cnt, n;
8235 int async_err = 0;
8236 struct iovec *iov;
8237 Py_buffer *buf;
8238
8239 if (!PySequence_Check(buffers)) {
8240 PyErr_SetString(PyExc_TypeError,
8241 "preadv2() arg 2 must be a sequence");
8242 return -1;
8243 }
8244
8245 cnt = PySequence_Size(buffers);
8246 if (cnt < 0) {
8247 return -1;
8248 }
8249
8250#ifndef HAVE_PREADV2
8251 if(flags != 0) {
8252 argument_unavailable_error("preadv2", "flags");
8253 return -1;
8254 }
8255#endif
8256
8257 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8258 return -1;
8259 }
8260#ifdef HAVE_PREADV2
8261 do {
8262 Py_BEGIN_ALLOW_THREADS
8263 _Py_BEGIN_SUPPRESS_IPH
8264 n = preadv2(fd, iov, cnt, offset, flags);
8265 _Py_END_SUPPRESS_IPH
8266 Py_END_ALLOW_THREADS
8267 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8268#else
8269 do {
8270 Py_BEGIN_ALLOW_THREADS
8271 _Py_BEGIN_SUPPRESS_IPH
8272 n = preadv(fd, iov, cnt, offset);
8273 _Py_END_SUPPRESS_IPH
8274 Py_END_ALLOW_THREADS
8275 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8276#endif
8277
8278 iov_cleanup(iov, buf, cnt);
8279 if (n < 0) {
8280 if (!async_err) {
8281 posix_error();
8282 }
8283 return -1;
8284 }
8285
8286 return n;
8287}
8288#endif /* HAVE_PREADV */
8289
Larry Hastings2f936352014-08-05 14:04:04 +10008290
8291/*[clinic input]
8292os.write -> Py_ssize_t
8293
8294 fd: int
8295 data: Py_buffer
8296 /
8297
8298Write a bytes object to a file descriptor.
8299[clinic start generated code]*/
8300
Larry Hastings2f936352014-08-05 14:04:04 +10008301static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008302os_write_impl(PyObject *module, int fd, Py_buffer *data)
8303/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008304{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008305 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008306}
8307
8308#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008309PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008310"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008311sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008312 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008313Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008314
Larry Hastings2f936352014-08-05 14:04:04 +10008315/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008316static PyObject *
8317posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8318{
8319 int in, out;
8320 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008321 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008322 off_t offset;
8323
8324#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8325#ifndef __APPLE__
8326 Py_ssize_t len;
8327#endif
8328 PyObject *headers = NULL, *trailers = NULL;
8329 Py_buffer *hbuf, *tbuf;
8330 off_t sbytes;
8331 struct sf_hdtr sf;
8332 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008333 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008334 static char *keywords[] = {"out", "in",
8335 "offset", "count",
8336 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008337
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008338 sf.headers = NULL;
8339 sf.trailers = NULL;
8340
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008341#ifdef __APPLE__
8342 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008343 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008344#else
8345 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008346 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008347#endif
8348 &headers, &trailers, &flags))
8349 return NULL;
8350 if (headers != NULL) {
8351 if (!PySequence_Check(headers)) {
8352 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008353 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008354 return NULL;
8355 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008356 Py_ssize_t i = PySequence_Size(headers);
8357 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008358 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008359 if (i > INT_MAX) {
8360 PyErr_SetString(PyExc_OverflowError,
8361 "sendfile() header is too large");
8362 return NULL;
8363 }
8364 if (i > 0) {
8365 sf.hdr_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008366 if (iov_setup(&(sf.headers), &hbuf,
8367 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008368 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008369#ifdef __APPLE__
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008370 for (i = 0; i < sf.hdr_cnt; i++) {
8371 Py_ssize_t blen = sf.headers[i].iov_len;
8372# define OFF_T_MAX 0x7fffffffffffffff
8373 if (sbytes >= OFF_T_MAX - blen) {
8374 PyErr_SetString(PyExc_OverflowError,
8375 "sendfile() header is too large");
8376 return NULL;
8377 }
8378 sbytes += blen;
8379 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008380#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008381 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008382 }
8383 }
8384 if (trailers != NULL) {
8385 if (!PySequence_Check(trailers)) {
8386 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008387 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008388 return NULL;
8389 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008390 Py_ssize_t i = PySequence_Size(trailers);
8391 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008392 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008393 if (i > INT_MAX) {
8394 PyErr_SetString(PyExc_OverflowError,
8395 "sendfile() trailer is too large");
8396 return NULL;
8397 }
8398 if (i > 0) {
8399 sf.trl_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008400 if (iov_setup(&(sf.trailers), &tbuf,
8401 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008402 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008403 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008404 }
8405 }
8406
Steve Dower8fc89802015-04-12 00:26:27 -04008407 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008408 do {
8409 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008410#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008411 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008412#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008413 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008414#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008415 Py_END_ALLOW_THREADS
8416 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008417 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008418
8419 if (sf.headers != NULL)
8420 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8421 if (sf.trailers != NULL)
8422 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8423
8424 if (ret < 0) {
8425 if ((errno == EAGAIN) || (errno == EBUSY)) {
8426 if (sbytes != 0) {
8427 // some data has been sent
8428 goto done;
8429 }
8430 else {
8431 // no data has been sent; upper application is supposed
8432 // to retry on EAGAIN or EBUSY
8433 return posix_error();
8434 }
8435 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008436 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008437 }
8438 goto done;
8439
8440done:
8441 #if !defined(HAVE_LARGEFILE_SUPPORT)
8442 return Py_BuildValue("l", sbytes);
8443 #else
8444 return Py_BuildValue("L", sbytes);
8445 #endif
8446
8447#else
8448 Py_ssize_t count;
8449 PyObject *offobj;
8450 static char *keywords[] = {"out", "in",
8451 "offset", "count", NULL};
8452 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8453 keywords, &out, &in, &offobj, &count))
8454 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008455#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008456 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008457 do {
8458 Py_BEGIN_ALLOW_THREADS
8459 ret = sendfile(out, in, NULL, count);
8460 Py_END_ALLOW_THREADS
8461 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008462 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008463 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008464 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008465 }
8466#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008467 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008468 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008469
8470 do {
8471 Py_BEGIN_ALLOW_THREADS
8472 ret = sendfile(out, in, &offset, count);
8473 Py_END_ALLOW_THREADS
8474 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008475 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008476 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008477 return Py_BuildValue("n", ret);
8478#endif
8479}
Larry Hastings2f936352014-08-05 14:04:04 +10008480#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008481
Larry Hastings2f936352014-08-05 14:04:04 +10008482
8483/*[clinic input]
8484os.fstat
8485
8486 fd : int
8487
8488Perform a stat system call on the given file descriptor.
8489
8490Like stat(), but for an open file descriptor.
8491Equivalent to os.stat(fd).
8492[clinic start generated code]*/
8493
Larry Hastings2f936352014-08-05 14:04:04 +10008494static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008495os_fstat_impl(PyObject *module, int fd)
8496/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008497{
Victor Stinner8c62be82010-05-06 00:08:46 +00008498 STRUCT_STAT st;
8499 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008500 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008501
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008502 do {
8503 Py_BEGIN_ALLOW_THREADS
8504 res = FSTAT(fd, &st);
8505 Py_END_ALLOW_THREADS
8506 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008507 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008508#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008509 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008510#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008511 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008512#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008513 }
Tim Peters5aa91602002-01-30 05:46:57 +00008514
Victor Stinner4195b5c2012-02-08 23:03:19 +01008515 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008516}
8517
Larry Hastings2f936352014-08-05 14:04:04 +10008518
8519/*[clinic input]
8520os.isatty -> bool
8521 fd: int
8522 /
8523
8524Return True if the fd is connected to a terminal.
8525
8526Return True if the file descriptor is an open file descriptor
8527connected to the slave end of a terminal.
8528[clinic start generated code]*/
8529
Larry Hastings2f936352014-08-05 14:04:04 +10008530static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008531os_isatty_impl(PyObject *module, int fd)
8532/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008533{
Steve Dower8fc89802015-04-12 00:26:27 -04008534 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008535 _Py_BEGIN_SUPPRESS_IPH
8536 return_value = isatty(fd);
8537 _Py_END_SUPPRESS_IPH
8538 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008539}
8540
8541
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008542#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008543/*[clinic input]
8544os.pipe
8545
8546Create a pipe.
8547
8548Returns a tuple of two file descriptors:
8549 (read_fd, write_fd)
8550[clinic start generated code]*/
8551
Larry Hastings2f936352014-08-05 14:04:04 +10008552static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008553os_pipe_impl(PyObject *module)
8554/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008555{
Victor Stinner8c62be82010-05-06 00:08:46 +00008556 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008557#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008558 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008559 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008560 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008561#else
8562 int res;
8563#endif
8564
8565#ifdef MS_WINDOWS
8566 attr.nLength = sizeof(attr);
8567 attr.lpSecurityDescriptor = NULL;
8568 attr.bInheritHandle = FALSE;
8569
8570 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008571 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008572 ok = CreatePipe(&read, &write, &attr, 0);
8573 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008574 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8575 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008576 if (fds[0] == -1 || fds[1] == -1) {
8577 CloseHandle(read);
8578 CloseHandle(write);
8579 ok = 0;
8580 }
8581 }
Steve Dowerc3630612016-11-19 18:41:16 -08008582 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008583 Py_END_ALLOW_THREADS
8584
Victor Stinner8c62be82010-05-06 00:08:46 +00008585 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008586 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008587#else
8588
8589#ifdef HAVE_PIPE2
8590 Py_BEGIN_ALLOW_THREADS
8591 res = pipe2(fds, O_CLOEXEC);
8592 Py_END_ALLOW_THREADS
8593
8594 if (res != 0 && errno == ENOSYS)
8595 {
8596#endif
8597 Py_BEGIN_ALLOW_THREADS
8598 res = pipe(fds);
8599 Py_END_ALLOW_THREADS
8600
8601 if (res == 0) {
8602 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8603 close(fds[0]);
8604 close(fds[1]);
8605 return NULL;
8606 }
8607 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8608 close(fds[0]);
8609 close(fds[1]);
8610 return NULL;
8611 }
8612 }
8613#ifdef HAVE_PIPE2
8614 }
8615#endif
8616
8617 if (res != 0)
8618 return PyErr_SetFromErrno(PyExc_OSError);
8619#endif /* !MS_WINDOWS */
8620 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008621}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008622#endif /* HAVE_PIPE */
8623
Larry Hastings2f936352014-08-05 14:04:04 +10008624
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008625#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008626/*[clinic input]
8627os.pipe2
8628
8629 flags: int
8630 /
8631
8632Create a pipe with flags set atomically.
8633
8634Returns a tuple of two file descriptors:
8635 (read_fd, write_fd)
8636
8637flags can be constructed by ORing together one or more of these values:
8638O_NONBLOCK, O_CLOEXEC.
8639[clinic start generated code]*/
8640
Larry Hastings2f936352014-08-05 14:04:04 +10008641static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008642os_pipe2_impl(PyObject *module, int flags)
8643/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008644{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008645 int fds[2];
8646 int res;
8647
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008648 res = pipe2(fds, flags);
8649 if (res != 0)
8650 return posix_error();
8651 return Py_BuildValue("(ii)", fds[0], fds[1]);
8652}
8653#endif /* HAVE_PIPE2 */
8654
Larry Hastings2f936352014-08-05 14:04:04 +10008655
Ross Lagerwall7807c352011-03-17 20:20:30 +02008656#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008657/*[clinic input]
8658os.writev -> Py_ssize_t
8659 fd: int
8660 buffers: object
8661 /
8662
8663Iterate over buffers, and write the contents of each to a file descriptor.
8664
8665Returns the total number of bytes written.
8666buffers must be a sequence of bytes-like objects.
8667[clinic start generated code]*/
8668
Larry Hastings2f936352014-08-05 14:04:04 +10008669static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008670os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8671/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008672{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008673 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008674 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008675 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008676 struct iovec *iov;
8677 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008678
8679 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008680 PyErr_SetString(PyExc_TypeError,
8681 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008682 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008683 }
Larry Hastings2f936352014-08-05 14:04:04 +10008684 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008685 if (cnt < 0)
8686 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008687
Larry Hastings2f936352014-08-05 14:04:04 +10008688 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8689 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008690 }
8691
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008692 do {
8693 Py_BEGIN_ALLOW_THREADS
8694 result = writev(fd, iov, cnt);
8695 Py_END_ALLOW_THREADS
8696 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008697
8698 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008699 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008700 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008701
Georg Brandl306336b2012-06-24 12:55:33 +02008702 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008703}
Larry Hastings2f936352014-08-05 14:04:04 +10008704#endif /* HAVE_WRITEV */
8705
8706
8707#ifdef HAVE_PWRITE
8708/*[clinic input]
8709os.pwrite -> Py_ssize_t
8710
8711 fd: int
8712 buffer: Py_buffer
8713 offset: Py_off_t
8714 /
8715
8716Write bytes to a file descriptor starting at a particular offset.
8717
8718Write buffer to fd, starting at offset bytes from the beginning of
8719the file. Returns the number of bytes writte. Does not change the
8720current file offset.
8721[clinic start generated code]*/
8722
Larry Hastings2f936352014-08-05 14:04:04 +10008723static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008724os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8725/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008726{
8727 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008728 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008729
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008730 do {
8731 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008732 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008733 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008734 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008735 Py_END_ALLOW_THREADS
8736 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008737
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008738 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008739 posix_error();
8740 return size;
8741}
8742#endif /* HAVE_PWRITE */
8743
Pablo Galindo4defba32018-01-27 16:16:37 +00008744#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8745/*[clinic input]
8746os.pwritev -> Py_ssize_t
8747
8748 fd: int
8749 buffers: object
8750 offset: Py_off_t
8751 flags: int = 0
8752 /
8753
8754Writes the contents of bytes-like objects to a file descriptor at a given offset.
8755
8756Combines the functionality of writev() and pwrite(). All buffers must be a sequence
8757of bytes-like objects. Buffers are processed in array order. Entire contents of first
8758buffer is written before proceeding to second, and so on. The operating system may
8759set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
8760This function writes the contents of each object to the file descriptor and returns
8761the total number of bytes written.
8762
8763The flags argument contains a bitwise OR of zero or more of the following flags:
8764
8765- RWF_DSYNC
8766- RWF_SYNC
8767
8768Using non-zero flags requires Linux 4.7 or newer.
8769[clinic start generated code]*/
8770
8771static Py_ssize_t
8772os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8773 int flags)
8774/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
8775{
8776 Py_ssize_t cnt;
8777 Py_ssize_t result;
8778 int async_err = 0;
8779 struct iovec *iov;
8780 Py_buffer *buf;
8781
8782 if (!PySequence_Check(buffers)) {
8783 PyErr_SetString(PyExc_TypeError,
8784 "pwritev() arg 2 must be a sequence");
8785 return -1;
8786 }
8787
8788 cnt = PySequence_Size(buffers);
8789 if (cnt < 0) {
8790 return -1;
8791 }
8792
8793#ifndef HAVE_PWRITEV2
8794 if(flags != 0) {
8795 argument_unavailable_error("pwritev2", "flags");
8796 return -1;
8797 }
8798#endif
8799
8800 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8801 return -1;
8802 }
8803#ifdef HAVE_PWRITEV2
8804 do {
8805 Py_BEGIN_ALLOW_THREADS
8806 _Py_BEGIN_SUPPRESS_IPH
8807 result = pwritev2(fd, iov, cnt, offset, flags);
8808 _Py_END_SUPPRESS_IPH
8809 Py_END_ALLOW_THREADS
8810 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8811#else
8812 do {
8813 Py_BEGIN_ALLOW_THREADS
8814 _Py_BEGIN_SUPPRESS_IPH
8815 result = pwritev(fd, iov, cnt, offset);
8816 _Py_END_SUPPRESS_IPH
8817 Py_END_ALLOW_THREADS
8818 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8819#endif
8820
8821 iov_cleanup(iov, buf, cnt);
8822 if (result < 0) {
8823 if (!async_err) {
8824 posix_error();
8825 }
8826 return -1;
8827 }
8828
8829 return result;
8830}
8831#endif /* HAVE_PWRITEV */
8832
8833
8834
Larry Hastings2f936352014-08-05 14:04:04 +10008835
8836#ifdef HAVE_MKFIFO
8837/*[clinic input]
8838os.mkfifo
8839
8840 path: path_t
8841 mode: int=0o666
8842 *
8843 dir_fd: dir_fd(requires='mkfifoat')=None
8844
8845Create a "fifo" (a POSIX named pipe).
8846
8847If dir_fd is not None, it should be a file descriptor open to a directory,
8848 and path should be relative; path will then be relative to that directory.
8849dir_fd may not be implemented on your platform.
8850 If it is unavailable, using it will raise a NotImplementedError.
8851[clinic start generated code]*/
8852
Larry Hastings2f936352014-08-05 14:04:04 +10008853static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008854os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8855/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008856{
8857 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008858 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008859
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008860 do {
8861 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008862#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008863 if (dir_fd != DEFAULT_DIR_FD)
8864 result = mkfifoat(dir_fd, path->narrow, mode);
8865 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008866#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008867 result = mkfifo(path->narrow, mode);
8868 Py_END_ALLOW_THREADS
8869 } while (result != 0 && errno == EINTR &&
8870 !(async_err = PyErr_CheckSignals()));
8871 if (result != 0)
8872 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008873
8874 Py_RETURN_NONE;
8875}
8876#endif /* HAVE_MKFIFO */
8877
8878
8879#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8880/*[clinic input]
8881os.mknod
8882
8883 path: path_t
8884 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008885 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008886 *
8887 dir_fd: dir_fd(requires='mknodat')=None
8888
8889Create a node in the file system.
8890
8891Create a node in the file system (file, device special file or named pipe)
8892at path. mode specifies both the permissions to use and the
8893type of node to be created, being combined (bitwise OR) with one of
8894S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8895device defines the newly created device special file (probably using
8896os.makedev()). Otherwise device is ignored.
8897
8898If dir_fd is not None, it should be a file descriptor open to a directory,
8899 and path should be relative; path will then be relative to that directory.
8900dir_fd may not be implemented on your platform.
8901 If it is unavailable, using it will raise a NotImplementedError.
8902[clinic start generated code]*/
8903
Larry Hastings2f936352014-08-05 14:04:04 +10008904static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008905os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008906 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008907/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008908{
8909 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008910 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008911
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008912 do {
8913 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008914#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008915 if (dir_fd != DEFAULT_DIR_FD)
8916 result = mknodat(dir_fd, path->narrow, mode, device);
8917 else
Larry Hastings2f936352014-08-05 14:04:04 +10008918#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008919 result = mknod(path->narrow, mode, device);
8920 Py_END_ALLOW_THREADS
8921 } while (result != 0 && errno == EINTR &&
8922 !(async_err = PyErr_CheckSignals()));
8923 if (result != 0)
8924 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008925
8926 Py_RETURN_NONE;
8927}
8928#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8929
8930
8931#ifdef HAVE_DEVICE_MACROS
8932/*[clinic input]
8933os.major -> unsigned_int
8934
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008935 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008936 /
8937
8938Extracts a device major number from a raw device number.
8939[clinic start generated code]*/
8940
Larry Hastings2f936352014-08-05 14:04:04 +10008941static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008942os_major_impl(PyObject *module, dev_t device)
8943/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008944{
8945 return major(device);
8946}
8947
8948
8949/*[clinic input]
8950os.minor -> unsigned_int
8951
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008952 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008953 /
8954
8955Extracts a device minor number from a raw device number.
8956[clinic start generated code]*/
8957
Larry Hastings2f936352014-08-05 14:04:04 +10008958static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008959os_minor_impl(PyObject *module, dev_t device)
8960/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008961{
8962 return minor(device);
8963}
8964
8965
8966/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008967os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008968
8969 major: int
8970 minor: int
8971 /
8972
8973Composes a raw device number from the major and minor device numbers.
8974[clinic start generated code]*/
8975
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008976static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008977os_makedev_impl(PyObject *module, int major, int minor)
8978/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008979{
8980 return makedev(major, minor);
8981}
8982#endif /* HAVE_DEVICE_MACROS */
8983
8984
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008985#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008986/*[clinic input]
8987os.ftruncate
8988
8989 fd: int
8990 length: Py_off_t
8991 /
8992
8993Truncate a file, specified by file descriptor, to a specific length.
8994[clinic start generated code]*/
8995
Larry Hastings2f936352014-08-05 14:04:04 +10008996static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008997os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8998/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008999{
9000 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009001 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009002
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009003 do {
9004 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009005 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009006#ifdef MS_WINDOWS
9007 result = _chsize_s(fd, length);
9008#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009009 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009010#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009011 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009012 Py_END_ALLOW_THREADS
9013 } while (result != 0 && errno == EINTR &&
9014 !(async_err = PyErr_CheckSignals()));
9015 if (result != 0)
9016 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009017 Py_RETURN_NONE;
9018}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009019#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009020
9021
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009022#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009023/*[clinic input]
9024os.truncate
9025 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9026 length: Py_off_t
9027
9028Truncate a file, specified by path, to a specific length.
9029
9030On some platforms, path may also be specified as an open file descriptor.
9031 If this functionality is unavailable, using it raises an exception.
9032[clinic start generated code]*/
9033
Larry Hastings2f936352014-08-05 14:04:04 +10009034static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009035os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9036/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009037{
9038 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009039#ifdef MS_WINDOWS
9040 int fd;
9041#endif
9042
9043 if (path->fd != -1)
9044 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009045
9046 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009047 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009048#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009049 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009050 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009051 result = -1;
9052 else {
9053 result = _chsize_s(fd, length);
9054 close(fd);
9055 if (result < 0)
9056 errno = result;
9057 }
9058#else
9059 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009060#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009061 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009062 Py_END_ALLOW_THREADS
9063 if (result < 0)
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07009064 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009065
9066 Py_RETURN_NONE;
9067}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009068#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009069
Ross Lagerwall7807c352011-03-17 20:20:30 +02009070
Victor Stinnerd6b17692014-09-30 12:20:05 +02009071/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9072 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9073 defined, which is the case in Python on AIX. AIX bug report:
9074 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9075#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9076# define POSIX_FADVISE_AIX_BUG
9077#endif
9078
Victor Stinnerec39e262014-09-30 12:35:58 +02009079
Victor Stinnerd6b17692014-09-30 12:20:05 +02009080#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009081/*[clinic input]
9082os.posix_fallocate
9083
9084 fd: int
9085 offset: Py_off_t
9086 length: Py_off_t
9087 /
9088
9089Ensure a file has allocated at least a particular number of bytes on disk.
9090
9091Ensure that the file specified by fd encompasses a range of bytes
9092starting at offset bytes from the beginning and continuing for length bytes.
9093[clinic start generated code]*/
9094
Larry Hastings2f936352014-08-05 14:04:04 +10009095static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009096os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009097 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009098/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009099{
9100 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009101 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009102
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009103 do {
9104 Py_BEGIN_ALLOW_THREADS
9105 result = posix_fallocate(fd, offset, length);
9106 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009107 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9108
9109 if (result == 0)
9110 Py_RETURN_NONE;
9111
9112 if (async_err)
9113 return NULL;
9114
9115 errno = result;
9116 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009117}
Victor Stinnerec39e262014-09-30 12:35:58 +02009118#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009119
Ross Lagerwall7807c352011-03-17 20:20:30 +02009120
Victor Stinnerd6b17692014-09-30 12:20:05 +02009121#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009122/*[clinic input]
9123os.posix_fadvise
9124
9125 fd: int
9126 offset: Py_off_t
9127 length: Py_off_t
9128 advice: int
9129 /
9130
9131Announce an intention to access data in a specific pattern.
9132
9133Announce an intention to access data in a specific pattern, thus allowing
9134the kernel to make optimizations.
9135The advice applies to the region of the file specified by fd starting at
9136offset and continuing for length bytes.
9137advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9138POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9139POSIX_FADV_DONTNEED.
9140[clinic start generated code]*/
9141
Larry Hastings2f936352014-08-05 14:04:04 +10009142static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009143os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009144 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009145/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009146{
9147 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009148 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009149
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009150 do {
9151 Py_BEGIN_ALLOW_THREADS
9152 result = posix_fadvise(fd, offset, length, advice);
9153 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009154 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9155
9156 if (result == 0)
9157 Py_RETURN_NONE;
9158
9159 if (async_err)
9160 return NULL;
9161
9162 errno = result;
9163 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009164}
Victor Stinnerec39e262014-09-30 12:35:58 +02009165#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009166
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009167#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009168
Fred Drake762e2061999-08-26 17:23:54 +00009169/* Save putenv() parameters as values here, so we can collect them when they
9170 * get re-set with another call for the same key. */
9171static PyObject *posix_putenv_garbage;
9172
Larry Hastings2f936352014-08-05 14:04:04 +10009173static void
9174posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009175{
Larry Hastings2f936352014-08-05 14:04:04 +10009176 /* Install the first arg and newstr in posix_putenv_garbage;
9177 * this will cause previous value to be collected. This has to
9178 * happen after the real putenv() call because the old value
9179 * was still accessible until then. */
9180 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9181 /* really not much we can do; just leak */
9182 PyErr_Clear();
9183 else
9184 Py_DECREF(value);
9185}
9186
9187
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009188#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009189/*[clinic input]
9190os.putenv
9191
9192 name: unicode
9193 value: unicode
9194 /
9195
9196Change or add an environment variable.
9197[clinic start generated code]*/
9198
Larry Hastings2f936352014-08-05 14:04:04 +10009199static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009200os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9201/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009202{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009203 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009204 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009205
Serhiy Storchaka77703942017-06-25 07:33:01 +03009206 /* Search from index 1 because on Windows starting '=' is allowed for
9207 defining hidden environment variables. */
9208 if (PyUnicode_GET_LENGTH(name) == 0 ||
9209 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9210 {
9211 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9212 return NULL;
9213 }
Larry Hastings2f936352014-08-05 14:04:04 +10009214 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9215 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009216 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009217 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009218
9219 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9220 if (env == NULL)
9221 goto error;
9222 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009223 PyErr_Format(PyExc_ValueError,
9224 "the environment variable is longer than %u characters",
9225 _MAX_ENV);
9226 goto error;
9227 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009228 if (wcslen(env) != (size_t)size) {
9229 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009230 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009231 }
9232
Larry Hastings2f936352014-08-05 14:04:04 +10009233 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009234 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009235 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009236 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009237
Larry Hastings2f936352014-08-05 14:04:04 +10009238 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009239 Py_RETURN_NONE;
9240
9241error:
Larry Hastings2f936352014-08-05 14:04:04 +10009242 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009243 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009244}
Larry Hastings2f936352014-08-05 14:04:04 +10009245#else /* MS_WINDOWS */
9246/*[clinic input]
9247os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009248
Larry Hastings2f936352014-08-05 14:04:04 +10009249 name: FSConverter
9250 value: FSConverter
9251 /
9252
9253Change or add an environment variable.
9254[clinic start generated code]*/
9255
Larry Hastings2f936352014-08-05 14:04:04 +10009256static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009257os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9258/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009259{
9260 PyObject *bytes = NULL;
9261 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009262 const char *name_string = PyBytes_AS_STRING(name);
9263 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009264
Serhiy Storchaka77703942017-06-25 07:33:01 +03009265 if (strchr(name_string, '=') != NULL) {
9266 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9267 return NULL;
9268 }
Larry Hastings2f936352014-08-05 14:04:04 +10009269 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9270 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009271 return NULL;
9272 }
9273
9274 env = PyBytes_AS_STRING(bytes);
9275 if (putenv(env)) {
9276 Py_DECREF(bytes);
9277 return posix_error();
9278 }
9279
9280 posix_putenv_garbage_setitem(name, bytes);
9281 Py_RETURN_NONE;
9282}
9283#endif /* MS_WINDOWS */
9284#endif /* HAVE_PUTENV */
9285
9286
9287#ifdef HAVE_UNSETENV
9288/*[clinic input]
9289os.unsetenv
9290 name: FSConverter
9291 /
9292
9293Delete an environment variable.
9294[clinic start generated code]*/
9295
Larry Hastings2f936352014-08-05 14:04:04 +10009296static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009297os_unsetenv_impl(PyObject *module, PyObject *name)
9298/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009299{
Victor Stinner984890f2011-11-24 13:53:38 +01009300#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009301 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009302#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009303
Victor Stinner984890f2011-11-24 13:53:38 +01009304#ifdef HAVE_BROKEN_UNSETENV
9305 unsetenv(PyBytes_AS_STRING(name));
9306#else
Victor Stinner65170952011-11-22 22:16:17 +01009307 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009308 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009309 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009310#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009311
Victor Stinner8c62be82010-05-06 00:08:46 +00009312 /* Remove the key from posix_putenv_garbage;
9313 * this will cause it to be collected. This has to
9314 * happen after the real unsetenv() call because the
9315 * old value was still accessible until then.
9316 */
Victor Stinner65170952011-11-22 22:16:17 +01009317 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009318 /* really not much we can do; just leak */
9319 PyErr_Clear();
9320 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009321 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009322}
Larry Hastings2f936352014-08-05 14:04:04 +10009323#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009324
Larry Hastings2f936352014-08-05 14:04:04 +10009325
9326/*[clinic input]
9327os.strerror
9328
9329 code: int
9330 /
9331
9332Translate an error code to a message string.
9333[clinic start generated code]*/
9334
Larry Hastings2f936352014-08-05 14:04:04 +10009335static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009336os_strerror_impl(PyObject *module, int code)
9337/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009338{
9339 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009340 if (message == NULL) {
9341 PyErr_SetString(PyExc_ValueError,
9342 "strerror() argument out of range");
9343 return NULL;
9344 }
Victor Stinner1b579672011-12-17 05:47:23 +01009345 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009346}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009347
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009348
Guido van Rossumc9641791998-08-04 15:26:23 +00009349#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009350#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009351/*[clinic input]
9352os.WCOREDUMP -> bool
9353
9354 status: int
9355 /
9356
9357Return True if the process returning status was dumped to a core file.
9358[clinic start generated code]*/
9359
Larry Hastings2f936352014-08-05 14:04:04 +10009360static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009361os_WCOREDUMP_impl(PyObject *module, int status)
9362/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009363{
9364 WAIT_TYPE wait_status;
9365 WAIT_STATUS_INT(wait_status) = status;
9366 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009367}
9368#endif /* WCOREDUMP */
9369
Larry Hastings2f936352014-08-05 14:04:04 +10009370
Fred Drake106c1a02002-04-23 15:58:02 +00009371#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009372/*[clinic input]
9373os.WIFCONTINUED -> bool
9374
9375 status: int
9376
9377Return True if a particular process was continued from a job control stop.
9378
9379Return True if the process returning status was continued from a
9380job control stop.
9381[clinic start generated code]*/
9382
Larry Hastings2f936352014-08-05 14:04:04 +10009383static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009384os_WIFCONTINUED_impl(PyObject *module, int status)
9385/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009386{
9387 WAIT_TYPE wait_status;
9388 WAIT_STATUS_INT(wait_status) = status;
9389 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009390}
9391#endif /* WIFCONTINUED */
9392
Larry Hastings2f936352014-08-05 14:04:04 +10009393
Guido van Rossumc9641791998-08-04 15:26:23 +00009394#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009395/*[clinic input]
9396os.WIFSTOPPED -> bool
9397
9398 status: int
9399
9400Return True if the process returning status was stopped.
9401[clinic start generated code]*/
9402
Larry Hastings2f936352014-08-05 14:04:04 +10009403static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009404os_WIFSTOPPED_impl(PyObject *module, int status)
9405/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009406{
9407 WAIT_TYPE wait_status;
9408 WAIT_STATUS_INT(wait_status) = status;
9409 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009410}
9411#endif /* WIFSTOPPED */
9412
Larry Hastings2f936352014-08-05 14:04:04 +10009413
Guido van Rossumc9641791998-08-04 15:26:23 +00009414#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009415/*[clinic input]
9416os.WIFSIGNALED -> bool
9417
9418 status: int
9419
9420Return True if the process returning status was terminated by a signal.
9421[clinic start generated code]*/
9422
Larry Hastings2f936352014-08-05 14:04:04 +10009423static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009424os_WIFSIGNALED_impl(PyObject *module, int status)
9425/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009426{
9427 WAIT_TYPE wait_status;
9428 WAIT_STATUS_INT(wait_status) = status;
9429 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009430}
9431#endif /* WIFSIGNALED */
9432
Larry Hastings2f936352014-08-05 14:04:04 +10009433
Guido van Rossumc9641791998-08-04 15:26:23 +00009434#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009435/*[clinic input]
9436os.WIFEXITED -> bool
9437
9438 status: int
9439
9440Return True if the process returning status exited via the exit() system call.
9441[clinic start generated code]*/
9442
Larry Hastings2f936352014-08-05 14:04:04 +10009443static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009444os_WIFEXITED_impl(PyObject *module, int status)
9445/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009446{
9447 WAIT_TYPE wait_status;
9448 WAIT_STATUS_INT(wait_status) = status;
9449 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009450}
9451#endif /* WIFEXITED */
9452
Larry Hastings2f936352014-08-05 14:04:04 +10009453
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009454#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009455/*[clinic input]
9456os.WEXITSTATUS -> int
9457
9458 status: int
9459
9460Return the process return code from status.
9461[clinic start generated code]*/
9462
Larry Hastings2f936352014-08-05 14:04:04 +10009463static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009464os_WEXITSTATUS_impl(PyObject *module, int status)
9465/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009466{
9467 WAIT_TYPE wait_status;
9468 WAIT_STATUS_INT(wait_status) = status;
9469 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009470}
9471#endif /* WEXITSTATUS */
9472
Larry Hastings2f936352014-08-05 14:04:04 +10009473
Guido van Rossumc9641791998-08-04 15:26:23 +00009474#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009475/*[clinic input]
9476os.WTERMSIG -> int
9477
9478 status: int
9479
9480Return the signal that terminated the process that provided the status value.
9481[clinic start generated code]*/
9482
Larry Hastings2f936352014-08-05 14:04:04 +10009483static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009484os_WTERMSIG_impl(PyObject *module, int status)
9485/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009486{
9487 WAIT_TYPE wait_status;
9488 WAIT_STATUS_INT(wait_status) = status;
9489 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009490}
9491#endif /* WTERMSIG */
9492
Larry Hastings2f936352014-08-05 14:04:04 +10009493
Guido van Rossumc9641791998-08-04 15:26:23 +00009494#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009495/*[clinic input]
9496os.WSTOPSIG -> int
9497
9498 status: int
9499
9500Return the signal that stopped the process that provided the status value.
9501[clinic start generated code]*/
9502
Larry Hastings2f936352014-08-05 14:04:04 +10009503static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009504os_WSTOPSIG_impl(PyObject *module, int status)
9505/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009506{
9507 WAIT_TYPE wait_status;
9508 WAIT_STATUS_INT(wait_status) = status;
9509 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009510}
9511#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009512#endif /* HAVE_SYS_WAIT_H */
9513
9514
Thomas Wouters477c8d52006-05-27 19:21:47 +00009515#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009516#ifdef _SCO_DS
9517/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9518 needed definitions in sys/statvfs.h */
9519#define _SVID3
9520#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009521#include <sys/statvfs.h>
9522
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009523static PyObject*
9524_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9526 if (v == NULL)
9527 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009528
9529#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9531 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9532 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9533 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9534 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9535 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9536 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9537 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9538 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9539 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009540#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9542 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9543 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009544 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009546 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009548 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009550 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009552 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009554 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9556 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009557#endif
Michael Felt502d5512018-01-05 13:01:58 +01009558/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9559 * (issue #32390). */
9560#if defined(_AIX) && defined(_ALL_SOURCE)
9561 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9562#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009563 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009564#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009565 if (PyErr_Occurred()) {
9566 Py_DECREF(v);
9567 return NULL;
9568 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009569
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009571}
9572
Larry Hastings2f936352014-08-05 14:04:04 +10009573
9574/*[clinic input]
9575os.fstatvfs
9576 fd: int
9577 /
9578
9579Perform an fstatvfs system call on the given fd.
9580
9581Equivalent to statvfs(fd).
9582[clinic start generated code]*/
9583
Larry Hastings2f936352014-08-05 14:04:04 +10009584static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009585os_fstatvfs_impl(PyObject *module, int fd)
9586/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009587{
9588 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009589 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009591
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009592 do {
9593 Py_BEGIN_ALLOW_THREADS
9594 result = fstatvfs(fd, &st);
9595 Py_END_ALLOW_THREADS
9596 } while (result != 0 && errno == EINTR &&
9597 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009598 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009599 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009600
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009602}
Larry Hastings2f936352014-08-05 14:04:04 +10009603#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009604
9605
Thomas Wouters477c8d52006-05-27 19:21:47 +00009606#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009607#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009608/*[clinic input]
9609os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009610
Larry Hastings2f936352014-08-05 14:04:04 +10009611 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9612
9613Perform a statvfs system call on the given path.
9614
9615path may always be specified as a string.
9616On some platforms, path may also be specified as an open file descriptor.
9617 If this functionality is unavailable, using it raises an exception.
9618[clinic start generated code]*/
9619
Larry Hastings2f936352014-08-05 14:04:04 +10009620static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009621os_statvfs_impl(PyObject *module, path_t *path)
9622/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009623{
9624 int result;
9625 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009626
9627 Py_BEGIN_ALLOW_THREADS
9628#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009629 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009630#ifdef __APPLE__
9631 /* handle weak-linking on Mac OS X 10.3 */
9632 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009633 fd_specified("statvfs", path->fd);
9634 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009635 }
9636#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009637 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009638 }
9639 else
9640#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009641 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009642 Py_END_ALLOW_THREADS
9643
9644 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009645 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009646 }
9647
Larry Hastings2f936352014-08-05 14:04:04 +10009648 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009649}
Larry Hastings2f936352014-08-05 14:04:04 +10009650#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9651
Guido van Rossum94f6f721999-01-06 18:42:14 +00009652
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009653#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009654/*[clinic input]
9655os._getdiskusage
9656
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009657 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10009658
9659Return disk usage statistics about the given path as a (total, free) tuple.
9660[clinic start generated code]*/
9661
Larry Hastings2f936352014-08-05 14:04:04 +10009662static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009663os__getdiskusage_impl(PyObject *module, path_t *path)
9664/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009665{
9666 BOOL retval;
9667 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009668
9669 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009670 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009671 Py_END_ALLOW_THREADS
9672 if (retval == 0)
9673 return PyErr_SetFromWindowsErr(0);
9674
9675 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9676}
Larry Hastings2f936352014-08-05 14:04:04 +10009677#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009678
9679
Fred Drakec9680921999-12-13 16:37:25 +00009680/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9681 * It maps strings representing configuration variable names to
9682 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009683 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009684 * rarely-used constants. There are three separate tables that use
9685 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009686 *
9687 * This code is always included, even if none of the interfaces that
9688 * need it are included. The #if hackery needed to avoid it would be
9689 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009690 */
9691struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009692 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009693 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009694};
9695
Fred Drake12c6e2d1999-12-14 21:25:03 +00009696static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009697conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009698 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009699{
Christian Heimes217cfd12007-12-02 14:31:20 +00009700 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009701 int value = _PyLong_AsInt(arg);
9702 if (value == -1 && PyErr_Occurred())
9703 return 0;
9704 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009705 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009706 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009707 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009708 /* look up the value in the table using a binary search */
9709 size_t lo = 0;
9710 size_t mid;
9711 size_t hi = tablesize;
9712 int cmp;
9713 const char *confname;
9714 if (!PyUnicode_Check(arg)) {
9715 PyErr_SetString(PyExc_TypeError,
9716 "configuration names must be strings or integers");
9717 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009719 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009720 if (confname == NULL)
9721 return 0;
9722 while (lo < hi) {
9723 mid = (lo + hi) / 2;
9724 cmp = strcmp(confname, table[mid].name);
9725 if (cmp < 0)
9726 hi = mid;
9727 else if (cmp > 0)
9728 lo = mid + 1;
9729 else {
9730 *valuep = table[mid].value;
9731 return 1;
9732 }
9733 }
9734 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9735 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009737}
9738
9739
9740#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9741static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009742#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009744#endif
9745#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009747#endif
Fred Drakec9680921999-12-13 16:37:25 +00009748#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
9754#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009756#endif
9757#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009759#endif
9760#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
9763#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009765#endif
9766#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
9769#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
9772#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
9778#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009780#endif
9781#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009783#endif
9784#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009786#endif
9787#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009793#ifdef _PC_ACL_ENABLED
9794 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9795#endif
9796#ifdef _PC_MIN_HOLE_SIZE
9797 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9798#endif
9799#ifdef _PC_ALLOC_SIZE_MIN
9800 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9801#endif
9802#ifdef _PC_REC_INCR_XFER_SIZE
9803 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9804#endif
9805#ifdef _PC_REC_MAX_XFER_SIZE
9806 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9807#endif
9808#ifdef _PC_REC_MIN_XFER_SIZE
9809 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9810#endif
9811#ifdef _PC_REC_XFER_ALIGN
9812 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9813#endif
9814#ifdef _PC_SYMLINK_MAX
9815 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9816#endif
9817#ifdef _PC_XATTR_ENABLED
9818 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9819#endif
9820#ifdef _PC_XATTR_EXISTS
9821 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9822#endif
9823#ifdef _PC_TIMESTAMP_RESOLUTION
9824 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9825#endif
Fred Drakec9680921999-12-13 16:37:25 +00009826};
9827
Fred Drakec9680921999-12-13 16:37:25 +00009828static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009829conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009830{
9831 return conv_confname(arg, valuep, posix_constants_pathconf,
9832 sizeof(posix_constants_pathconf)
9833 / sizeof(struct constdef));
9834}
9835#endif
9836
Larry Hastings2f936352014-08-05 14:04:04 +10009837
Fred Drakec9680921999-12-13 16:37:25 +00009838#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009839/*[clinic input]
9840os.fpathconf -> long
9841
9842 fd: int
9843 name: path_confname
9844 /
9845
9846Return the configuration limit name for the file descriptor fd.
9847
9848If there is no limit, return -1.
9849[clinic start generated code]*/
9850
Larry Hastings2f936352014-08-05 14:04:04 +10009851static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009852os_fpathconf_impl(PyObject *module, int fd, int name)
9853/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009854{
9855 long limit;
9856
9857 errno = 0;
9858 limit = fpathconf(fd, name);
9859 if (limit == -1 && errno != 0)
9860 posix_error();
9861
9862 return limit;
9863}
9864#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009865
9866
9867#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009868/*[clinic input]
9869os.pathconf -> long
9870 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9871 name: path_confname
9872
9873Return the configuration limit name for the file or directory path.
9874
9875If there is no limit, return -1.
9876On some platforms, path may also be specified as an open file descriptor.
9877 If this functionality is unavailable, using it raises an exception.
9878[clinic start generated code]*/
9879
Larry Hastings2f936352014-08-05 14:04:04 +10009880static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009881os_pathconf_impl(PyObject *module, path_t *path, int name)
9882/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009883{
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009885
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009887#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009888 if (path->fd != -1)
9889 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009890 else
9891#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009892 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 if (limit == -1 && errno != 0) {
9894 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009895 /* could be a path or name problem */
9896 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009897 else
Larry Hastings2f936352014-08-05 14:04:04 +10009898 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 }
Larry Hastings2f936352014-08-05 14:04:04 +10009900
9901 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009902}
Larry Hastings2f936352014-08-05 14:04:04 +10009903#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009904
9905#ifdef HAVE_CONFSTR
9906static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009907#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009909#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009910#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009912#endif
9913#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009915#endif
Fred Draked86ed291999-12-15 15:34:33 +00009916#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009918#endif
9919#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009921#endif
9922#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009924#endif
9925#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009927#endif
Fred Drakec9680921999-12-13 16:37:25 +00009928#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
9946#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
9949#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
Fred Draked86ed291999-12-15 15:34:33 +00009952#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009954#endif
Fred Drakec9680921999-12-13 16:37:25 +00009955#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
Fred Draked86ed291999-12-15 15:34:33 +00009958#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009960#endif
9961#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009963#endif
9964#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009966#endif
9967#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009969#endif
Fred Drakec9680921999-12-13 16:37:25 +00009970#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
9982#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
Fred Draked86ed291999-12-15 15:34:33 +000010018#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010020#endif
10021#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010023#endif
10024#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010026#endif
10027#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010029#endif
10030#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010032#endif
10033#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010035#endif
10036#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010038#endif
10039#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010041#endif
10042#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010044#endif
10045#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010047#endif
10048#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010050#endif
10051#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010053#endif
10054#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010056#endif
Fred Drakec9680921999-12-13 16:37:25 +000010057};
10058
10059static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010060conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010061{
10062 return conv_confname(arg, valuep, posix_constants_confstr,
10063 sizeof(posix_constants_confstr)
10064 / sizeof(struct constdef));
10065}
10066
Larry Hastings2f936352014-08-05 14:04:04 +100010067
10068/*[clinic input]
10069os.confstr
10070
10071 name: confstr_confname
10072 /
10073
10074Return a string-valued system configuration variable.
10075[clinic start generated code]*/
10076
Larry Hastings2f936352014-08-05 14:04:04 +100010077static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010078os_confstr_impl(PyObject *module, int name)
10079/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010080{
10081 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010082 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010083 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010084
Victor Stinnercb043522010-09-10 23:49:04 +000010085 errno = 0;
10086 len = confstr(name, buffer, sizeof(buffer));
10087 if (len == 0) {
10088 if (errno) {
10089 posix_error();
10090 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010091 }
10092 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010093 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010094 }
10095 }
Victor Stinnercb043522010-09-10 23:49:04 +000010096
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010097 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010098 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010099 char *buf = PyMem_Malloc(len);
10100 if (buf == NULL)
10101 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010102 len2 = confstr(name, buf, len);
10103 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010104 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010105 PyMem_Free(buf);
10106 }
10107 else
10108 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010109 return result;
10110}
Larry Hastings2f936352014-08-05 14:04:04 +100010111#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010112
10113
10114#ifdef HAVE_SYSCONF
10115static struct constdef posix_constants_sysconf[] = {
10116#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
Fred Draked86ed291999-12-15 15:34:33 +000010146#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010148#endif
10149#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010151#endif
Fred Drakec9680921999-12-13 16:37:25 +000010152#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
Fred Drakec9680921999-12-13 16:37:25 +000010155#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
Fred Draked86ed291999-12-15 15:34:33 +000010170#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010172#endif
Fred Drakec9680921999-12-13 16:37:25 +000010173#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
Fred Draked86ed291999-12-15 15:34:33 +000010188#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010190#endif
Fred Drakec9680921999-12-13 16:37:25 +000010191#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
10224#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010225 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010226#endif
10227#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010229#endif
10230#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010232#endif
10233#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010235#endif
10236#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010237 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010238#endif
10239#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010241#endif
10242#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010243 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010244#endif
10245#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010247#endif
10248#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010250#endif
10251#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010253#endif
10254#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010256#endif
10257#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010258 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010259#endif
Fred Draked86ed291999-12-15 15:34:33 +000010260#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010262#endif
Fred Drakec9680921999-12-13 16:37:25 +000010263#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010265#endif
10266#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010268#endif
10269#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010271#endif
Fred Draked86ed291999-12-15 15:34:33 +000010272#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010274#endif
Fred Drakec9680921999-12-13 16:37:25 +000010275#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010277#endif
Fred Draked86ed291999-12-15 15:34:33 +000010278#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010280#endif
10281#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010283#endif
Fred Drakec9680921999-12-13 16:37:25 +000010284#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010286#endif
10287#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010289#endif
10290#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010292#endif
10293#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010295#endif
Fred Draked86ed291999-12-15 15:34:33 +000010296#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010298#endif
Fred Drakec9680921999-12-13 16:37:25 +000010299#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010300 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010301#endif
10302#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010304#endif
10305#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010307#endif
10308#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010309 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010310#endif
10311#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010313#endif
10314#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010316#endif
10317#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010318 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010319#endif
Fred Draked86ed291999-12-15 15:34:33 +000010320#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010322#endif
Fred Drakec9680921999-12-13 16:37:25 +000010323#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010325#endif
10326#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010328#endif
Fred Draked86ed291999-12-15 15:34:33 +000010329#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010331#endif
Fred Drakec9680921999-12-13 16:37:25 +000010332#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010334#endif
10335#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010337#endif
10338#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010340#endif
10341#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010343#endif
10344#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010346#endif
10347#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010349#endif
10350#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010352#endif
10353#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010355#endif
10356#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010358#endif
Fred Draked86ed291999-12-15 15:34:33 +000010359#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010360 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010361#endif
10362#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010364#endif
Fred Drakec9680921999-12-13 16:37:25 +000010365#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010367#endif
10368#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010369 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010370#endif
10371#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010372 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010373#endif
10374#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010375 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010376#endif
10377#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010378 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010379#endif
10380#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010382#endif
10383#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010384 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010385#endif
10386#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010387 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010388#endif
10389#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010390 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010391#endif
10392#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010393 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010394#endif
10395#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010396 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010397#endif
10398#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010399 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010400#endif
10401#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010402 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010403#endif
10404#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010405 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010406#endif
10407#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010408 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010409#endif
10410#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010412#endif
10413#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010415#endif
10416#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010418#endif
10419#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010421#endif
10422#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010423 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010424#endif
10425#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010426 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010427#endif
10428#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010429 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010430#endif
10431#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010432 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010433#endif
10434#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010435 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010436#endif
10437#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010438 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010439#endif
10440#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010441 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010442#endif
10443#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010444 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010445#endif
10446#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010447 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010448#endif
10449#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010450 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010451#endif
10452#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010453 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010454#endif
10455#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010456 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010457#endif
10458#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010459 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010460#endif
10461#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010462 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010463#endif
10464#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010466#endif
10467#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010468 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010469#endif
Fred Draked86ed291999-12-15 15:34:33 +000010470#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010471 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010472#endif
Fred Drakec9680921999-12-13 16:37:25 +000010473#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010474 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010475#endif
10476#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010477 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010478#endif
10479#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010480 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010481#endif
10482#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010483 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010484#endif
10485#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010487#endif
10488#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010489 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010490#endif
10491#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010492 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010493#endif
10494#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010495 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010496#endif
10497#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010498 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010499#endif
10500#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010501 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010502#endif
10503#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010504 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010505#endif
10506#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010508#endif
10509#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010510 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010511#endif
10512#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010513 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010514#endif
10515#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010517#endif
10518#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010519 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010520#endif
10521#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010523#endif
10524#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010526#endif
10527#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010529#endif
10530#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010531 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010532#endif
10533#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010534 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010535#endif
10536#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010538#endif
10539#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010540 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010541#endif
10542#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010544#endif
10545#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010546 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010547#endif
10548#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010550#endif
10551#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010552 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010553#endif
10554#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010555 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010556#endif
10557#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010558 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010559#endif
10560#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010561 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010562#endif
10563#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010564 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010565#endif
10566#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010567 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010568#endif
10569#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010570 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010571#endif
10572#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010573 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010574#endif
10575#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010576 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010577#endif
10578#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010579 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010580#endif
10581#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010582 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010583#endif
10584#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010585 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010586#endif
10587#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010589#endif
10590#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010591 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010592#endif
10593#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010594 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010595#endif
10596#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010598#endif
10599#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010600 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010601#endif
10602#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010604#endif
10605#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010606 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010607#endif
10608};
10609
10610static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010611conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010612{
10613 return conv_confname(arg, valuep, posix_constants_sysconf,
10614 sizeof(posix_constants_sysconf)
10615 / sizeof(struct constdef));
10616}
10617
Larry Hastings2f936352014-08-05 14:04:04 +100010618
10619/*[clinic input]
10620os.sysconf -> long
10621 name: sysconf_confname
10622 /
10623
10624Return an integer-valued system configuration variable.
10625[clinic start generated code]*/
10626
Larry Hastings2f936352014-08-05 14:04:04 +100010627static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010628os_sysconf_impl(PyObject *module, int name)
10629/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010630{
10631 long value;
10632
10633 errno = 0;
10634 value = sysconf(name);
10635 if (value == -1 && errno != 0)
10636 posix_error();
10637 return value;
10638}
10639#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010640
10641
Fred Drakebec628d1999-12-15 18:31:10 +000010642/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010643 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010644 * the exported dictionaries that are used to publish information about the
10645 * names available on the host platform.
10646 *
10647 * Sorting the table at runtime ensures that the table is properly ordered
10648 * when used, even for platforms we're not able to test on. It also makes
10649 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010650 */
Fred Drakebec628d1999-12-15 18:31:10 +000010651
10652static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010653cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010654{
10655 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010657 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010658 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010659
10660 return strcmp(c1->name, c2->name);
10661}
10662
10663static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010664setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010665 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010666{
Fred Drakebec628d1999-12-15 18:31:10 +000010667 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010668 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010669
10670 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10671 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010672 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010673 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010674
Barry Warsaw3155db32000-04-13 15:20:40 +000010675 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 PyObject *o = PyLong_FromLong(table[i].value);
10677 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10678 Py_XDECREF(o);
10679 Py_DECREF(d);
10680 return -1;
10681 }
10682 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010683 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010684 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010685}
10686
Fred Drakebec628d1999-12-15 18:31:10 +000010687/* Return -1 on failure, 0 on success. */
10688static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010689setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010690{
10691#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010692 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010693 sizeof(posix_constants_pathconf)
10694 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010695 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010696 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010697#endif
10698#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010699 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010700 sizeof(posix_constants_confstr)
10701 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010702 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010703 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010704#endif
10705#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010706 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010707 sizeof(posix_constants_sysconf)
10708 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010709 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010710 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010711#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010712 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010713}
Fred Draked86ed291999-12-15 15:34:33 +000010714
10715
Larry Hastings2f936352014-08-05 14:04:04 +100010716/*[clinic input]
10717os.abort
10718
10719Abort the interpreter immediately.
10720
10721This function 'dumps core' or otherwise fails in the hardest way possible
10722on the hosting operating system. This function never returns.
10723[clinic start generated code]*/
10724
Larry Hastings2f936352014-08-05 14:04:04 +100010725static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010726os_abort_impl(PyObject *module)
10727/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010728{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010729 abort();
10730 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010731#ifndef __clang__
10732 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10733 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10734 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010735 Py_FatalError("abort() called from Python code didn't abort!");
10736 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010737#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010738}
Fred Drakebec628d1999-12-15 18:31:10 +000010739
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010740#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010741/* Grab ShellExecute dynamically from shell32 */
10742static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010743static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10744 LPCWSTR, INT);
10745static int
10746check_ShellExecute()
10747{
10748 HINSTANCE hShell32;
10749
10750 /* only recheck */
10751 if (-1 == has_ShellExecute) {
10752 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010753 /* Security note: this call is not vulnerable to "DLL hijacking".
10754 SHELL32 is part of "KnownDLLs" and so Windows always load
10755 the system SHELL32.DLL, even if there is another SHELL32.DLL
10756 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010757 hShell32 = LoadLibraryW(L"SHELL32");
10758 Py_END_ALLOW_THREADS
10759 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010760 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10761 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010762 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010763 } else {
10764 has_ShellExecute = 0;
10765 }
10766 }
10767 return has_ShellExecute;
10768}
10769
10770
Steve Dowercc16be82016-09-08 10:35:16 -070010771/*[clinic input]
10772os.startfile
10773 filepath: path_t
10774 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010775
Steve Dowercc16be82016-09-08 10:35:16 -070010776startfile(filepath [, operation])
10777
10778Start a file with its associated application.
10779
10780When "operation" is not specified or "open", this acts like
10781double-clicking the file in Explorer, or giving the file name as an
10782argument to the DOS "start" command: the file is opened with whatever
10783application (if any) its extension is associated.
10784When another "operation" is given, it specifies what should be done with
10785the file. A typical operation is "print".
10786
10787startfile returns as soon as the associated application is launched.
10788There is no option to wait for the application to close, and no way
10789to retrieve the application's exit status.
10790
10791The filepath is relative to the current directory. If you want to use
10792an absolute path, make sure the first character is not a slash ("/");
10793the underlying Win32 ShellExecute function doesn't work if it is.
10794[clinic start generated code]*/
10795
10796static PyObject *
10797os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10798/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10799{
10800 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010801
10802 if(!check_ShellExecute()) {
10803 /* If the OS doesn't have ShellExecute, return a
10804 NotImplementedError. */
10805 return PyErr_Format(PyExc_NotImplementedError,
10806 "startfile not available on this platform");
10807 }
10808
Victor Stinner8c62be82010-05-06 00:08:46 +000010809 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010810 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010811 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010812 Py_END_ALLOW_THREADS
10813
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010815 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010816 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 }
Steve Dowercc16be82016-09-08 10:35:16 -070010818 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010819}
Larry Hastings2f936352014-08-05 14:04:04 +100010820#endif /* MS_WINDOWS */
10821
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010822
Martin v. Löwis438b5342002-12-27 10:16:42 +000010823#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010824/*[clinic input]
10825os.getloadavg
10826
10827Return average recent system load information.
10828
10829Return the number of processes in the system run queue averaged over
10830the last 1, 5, and 15 minutes as a tuple of three floats.
10831Raises OSError if the load average was unobtainable.
10832[clinic start generated code]*/
10833
Larry Hastings2f936352014-08-05 14:04:04 +100010834static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010835os_getloadavg_impl(PyObject *module)
10836/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010837{
10838 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010839 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010840 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10841 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010842 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010843 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010844}
Larry Hastings2f936352014-08-05 14:04:04 +100010845#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010846
Larry Hastings2f936352014-08-05 14:04:04 +100010847
10848/*[clinic input]
10849os.device_encoding
10850 fd: int
10851
10852Return a string describing the encoding of a terminal's file descriptor.
10853
10854The file descriptor must be attached to a terminal.
10855If the device is not a terminal, return None.
10856[clinic start generated code]*/
10857
Larry Hastings2f936352014-08-05 14:04:04 +100010858static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010859os_device_encoding_impl(PyObject *module, int fd)
10860/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010861{
Brett Cannonefb00c02012-02-29 18:31:31 -050010862 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010863}
10864
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010865
Larry Hastings2f936352014-08-05 14:04:04 +100010866#ifdef HAVE_SETRESUID
10867/*[clinic input]
10868os.setresuid
10869
10870 ruid: uid_t
10871 euid: uid_t
10872 suid: uid_t
10873 /
10874
10875Set the current process's real, effective, and saved user ids.
10876[clinic start generated code]*/
10877
Larry Hastings2f936352014-08-05 14:04:04 +100010878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010879os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10880/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010881{
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 if (setresuid(ruid, euid, suid) < 0)
10883 return posix_error();
10884 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010885}
Larry Hastings2f936352014-08-05 14:04:04 +100010886#endif /* HAVE_SETRESUID */
10887
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010888
10889#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010890/*[clinic input]
10891os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010892
Larry Hastings2f936352014-08-05 14:04:04 +100010893 rgid: gid_t
10894 egid: gid_t
10895 sgid: gid_t
10896 /
10897
10898Set the current process's real, effective, and saved group ids.
10899[clinic start generated code]*/
10900
Larry Hastings2f936352014-08-05 14:04:04 +100010901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010902os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10903/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010904{
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 if (setresgid(rgid, egid, sgid) < 0)
10906 return posix_error();
10907 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010908}
Larry Hastings2f936352014-08-05 14:04:04 +100010909#endif /* HAVE_SETRESGID */
10910
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010911
10912#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010913/*[clinic input]
10914os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010915
Larry Hastings2f936352014-08-05 14:04:04 +100010916Return a tuple of the current process's real, effective, and saved user ids.
10917[clinic start generated code]*/
10918
Larry Hastings2f936352014-08-05 14:04:04 +100010919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010920os_getresuid_impl(PyObject *module)
10921/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010922{
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 if (getresuid(&ruid, &euid, &suid) < 0)
10925 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010926 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10927 _PyLong_FromUid(euid),
10928 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010929}
Larry Hastings2f936352014-08-05 14:04:04 +100010930#endif /* HAVE_GETRESUID */
10931
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010932
10933#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010934/*[clinic input]
10935os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010936
Larry Hastings2f936352014-08-05 14:04:04 +100010937Return a tuple of the current process's real, effective, and saved group ids.
10938[clinic start generated code]*/
10939
Larry Hastings2f936352014-08-05 14:04:04 +100010940static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010941os_getresgid_impl(PyObject *module)
10942/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010943{
10944 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 if (getresgid(&rgid, &egid, &sgid) < 0)
10946 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010947 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10948 _PyLong_FromGid(egid),
10949 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010950}
Larry Hastings2f936352014-08-05 14:04:04 +100010951#endif /* HAVE_GETRESGID */
10952
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010953
Benjamin Peterson9428d532011-09-14 11:45:52 -040010954#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010955/*[clinic input]
10956os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010957
Larry Hastings2f936352014-08-05 14:04:04 +100010958 path: path_t(allow_fd=True)
10959 attribute: path_t
10960 *
10961 follow_symlinks: bool = True
10962
10963Return the value of extended attribute attribute on path.
10964
BNMetrics08026b12018-11-02 17:56:25 +000010965path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100010966If follow_symlinks is False, and the last element of the path is a symbolic
10967 link, getxattr will examine the symbolic link itself instead of the file
10968 the link points to.
10969
10970[clinic start generated code]*/
10971
Larry Hastings2f936352014-08-05 14:04:04 +100010972static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010973os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010974 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000010975/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010976{
10977 Py_ssize_t i;
10978 PyObject *buffer = NULL;
10979
10980 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10981 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010982
Larry Hastings9cf065c2012-06-22 16:30:09 -070010983 for (i = 0; ; i++) {
10984 void *ptr;
10985 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010986 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010987 Py_ssize_t buffer_size = buffer_sizes[i];
10988 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010989 path_error(path);
10990 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010991 }
10992 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10993 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010994 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010995 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010996
Larry Hastings9cf065c2012-06-22 16:30:09 -070010997 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010998 if (path->fd >= 0)
10999 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011000 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011001 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011002 else
Larry Hastings2f936352014-08-05 14:04:04 +100011003 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011004 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011005
Larry Hastings9cf065c2012-06-22 16:30:09 -070011006 if (result < 0) {
11007 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011008 if (errno == ERANGE)
11009 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011010 path_error(path);
11011 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011012 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011013
Larry Hastings9cf065c2012-06-22 16:30:09 -070011014 if (result != buffer_size) {
11015 /* Can only shrink. */
11016 _PyBytes_Resize(&buffer, result);
11017 }
11018 break;
11019 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011020
Larry Hastings9cf065c2012-06-22 16:30:09 -070011021 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011022}
11023
Larry Hastings2f936352014-08-05 14:04:04 +100011024
11025/*[clinic input]
11026os.setxattr
11027
11028 path: path_t(allow_fd=True)
11029 attribute: path_t
11030 value: Py_buffer
11031 flags: int = 0
11032 *
11033 follow_symlinks: bool = True
11034
11035Set extended attribute attribute on path to value.
11036
BNMetrics08026b12018-11-02 17:56:25 +000011037path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011038If follow_symlinks is False, and the last element of the path is a symbolic
11039 link, setxattr will modify the symbolic link itself instead of the file
11040 the link points to.
11041
11042[clinic start generated code]*/
11043
Benjamin Peterson799bd802011-08-31 22:15:17 -040011044static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011045os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011046 Py_buffer *value, int flags, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011047/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011048{
Larry Hastings2f936352014-08-05 14:04:04 +100011049 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011050
Larry Hastings2f936352014-08-05 14:04:04 +100011051 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011052 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011053
Benjamin Peterson799bd802011-08-31 22:15:17 -040011054 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011055 if (path->fd > -1)
11056 result = fsetxattr(path->fd, attribute->narrow,
11057 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011058 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011059 result = setxattr(path->narrow, attribute->narrow,
11060 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011061 else
Larry Hastings2f936352014-08-05 14:04:04 +100011062 result = lsetxattr(path->narrow, attribute->narrow,
11063 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011064 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011065
Larry Hastings9cf065c2012-06-22 16:30:09 -070011066 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011067 path_error(path);
11068 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011069 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011070
Larry Hastings2f936352014-08-05 14:04:04 +100011071 Py_RETURN_NONE;
11072}
11073
11074
11075/*[clinic input]
11076os.removexattr
11077
11078 path: path_t(allow_fd=True)
11079 attribute: path_t
11080 *
11081 follow_symlinks: bool = True
11082
11083Remove extended attribute attribute on path.
11084
BNMetrics08026b12018-11-02 17:56:25 +000011085path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011086If follow_symlinks is False, and the last element of the path is a symbolic
11087 link, removexattr will modify the symbolic link itself instead of the file
11088 the link points to.
11089
11090[clinic start generated code]*/
11091
Larry Hastings2f936352014-08-05 14:04:04 +100011092static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011093os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011094 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011095/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011096{
11097 ssize_t result;
11098
11099 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11100 return NULL;
11101
11102 Py_BEGIN_ALLOW_THREADS;
11103 if (path->fd > -1)
11104 result = fremovexattr(path->fd, attribute->narrow);
11105 else if (follow_symlinks)
11106 result = removexattr(path->narrow, attribute->narrow);
11107 else
11108 result = lremovexattr(path->narrow, attribute->narrow);
11109 Py_END_ALLOW_THREADS;
11110
11111 if (result) {
11112 return path_error(path);
11113 }
11114
11115 Py_RETURN_NONE;
11116}
11117
11118
11119/*[clinic input]
11120os.listxattr
11121
11122 path: path_t(allow_fd=True, nullable=True) = None
11123 *
11124 follow_symlinks: bool = True
11125
11126Return a list of extended attributes on path.
11127
BNMetrics08026b12018-11-02 17:56:25 +000011128path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011129if path is None, listxattr will examine the current directory.
11130If follow_symlinks is False, and the last element of the path is a symbolic
11131 link, listxattr will examine the symbolic link itself instead of the file
11132 the link points to.
11133[clinic start generated code]*/
11134
Larry Hastings2f936352014-08-05 14:04:04 +100011135static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011136os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011137/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011138{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011139 Py_ssize_t i;
11140 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011141 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011142 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011143
Larry Hastings2f936352014-08-05 14:04:04 +100011144 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011145 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011146
Larry Hastings2f936352014-08-05 14:04:04 +100011147 name = path->narrow ? path->narrow : ".";
11148
Larry Hastings9cf065c2012-06-22 16:30:09 -070011149 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011150 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011151 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011152 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011153 Py_ssize_t buffer_size = buffer_sizes[i];
11154 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011155 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011156 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011157 break;
11158 }
11159 buffer = PyMem_MALLOC(buffer_size);
11160 if (!buffer) {
11161 PyErr_NoMemory();
11162 break;
11163 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011164
Larry Hastings9cf065c2012-06-22 16:30:09 -070011165 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011166 if (path->fd > -1)
11167 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011168 else if (follow_symlinks)
11169 length = listxattr(name, buffer, buffer_size);
11170 else
11171 length = llistxattr(name, buffer, buffer_size);
11172 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011173
Larry Hastings9cf065c2012-06-22 16:30:09 -070011174 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011175 if (errno == ERANGE) {
11176 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011177 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011178 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011179 }
Larry Hastings2f936352014-08-05 14:04:04 +100011180 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011181 break;
11182 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011183
Larry Hastings9cf065c2012-06-22 16:30:09 -070011184 result = PyList_New(0);
11185 if (!result) {
11186 goto exit;
11187 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011188
Larry Hastings9cf065c2012-06-22 16:30:09 -070011189 end = buffer + length;
11190 for (trace = start = buffer; trace != end; trace++) {
11191 if (!*trace) {
11192 int error;
11193 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11194 trace - start);
11195 if (!attribute) {
11196 Py_DECREF(result);
11197 result = NULL;
11198 goto exit;
11199 }
11200 error = PyList_Append(result, attribute);
11201 Py_DECREF(attribute);
11202 if (error) {
11203 Py_DECREF(result);
11204 result = NULL;
11205 goto exit;
11206 }
11207 start = trace + 1;
11208 }
11209 }
11210 break;
11211 }
11212exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011213 if (buffer)
11214 PyMem_FREE(buffer);
11215 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011216}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011217#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011218
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011219
Larry Hastings2f936352014-08-05 14:04:04 +100011220/*[clinic input]
11221os.urandom
11222
11223 size: Py_ssize_t
11224 /
11225
11226Return a bytes object containing random bytes suitable for cryptographic use.
11227[clinic start generated code]*/
11228
Larry Hastings2f936352014-08-05 14:04:04 +100011229static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011230os_urandom_impl(PyObject *module, Py_ssize_t size)
11231/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011232{
11233 PyObject *bytes;
11234 int result;
11235
Georg Brandl2fb477c2012-02-21 00:33:36 +010011236 if (size < 0)
11237 return PyErr_Format(PyExc_ValueError,
11238 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011239 bytes = PyBytes_FromStringAndSize(NULL, size);
11240 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011241 return NULL;
11242
Victor Stinnere66987e2016-09-06 16:33:52 -070011243 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011244 if (result == -1) {
11245 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011246 return NULL;
11247 }
Larry Hastings2f936352014-08-05 14:04:04 +100011248 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011249}
11250
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011251/* Terminal size querying */
11252
11253static PyTypeObject TerminalSizeType;
11254
11255PyDoc_STRVAR(TerminalSize_docstring,
11256 "A tuple of (columns, lines) for holding terminal window size");
11257
11258static PyStructSequence_Field TerminalSize_fields[] = {
11259 {"columns", "width of the terminal window in characters"},
11260 {"lines", "height of the terminal window in characters"},
11261 {NULL, NULL}
11262};
11263
11264static PyStructSequence_Desc TerminalSize_desc = {
11265 "os.terminal_size",
11266 TerminalSize_docstring,
11267 TerminalSize_fields,
11268 2,
11269};
11270
11271#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011272/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011273PyDoc_STRVAR(termsize__doc__,
11274 "Return the size of the terminal window as (columns, lines).\n" \
11275 "\n" \
11276 "The optional argument fd (default standard output) specifies\n" \
11277 "which file descriptor should be queried.\n" \
11278 "\n" \
11279 "If the file descriptor is not connected to a terminal, an OSError\n" \
11280 "is thrown.\n" \
11281 "\n" \
11282 "This function will only be defined if an implementation is\n" \
11283 "available for this system.\n" \
11284 "\n" \
11285 "shutil.get_terminal_size is the high-level function which should \n" \
11286 "normally be used, os.get_terminal_size is the low-level implementation.");
11287
11288static PyObject*
11289get_terminal_size(PyObject *self, PyObject *args)
11290{
11291 int columns, lines;
11292 PyObject *termsize;
11293
11294 int fd = fileno(stdout);
11295 /* Under some conditions stdout may not be connected and
11296 * fileno(stdout) may point to an invalid file descriptor. For example
11297 * GUI apps don't have valid standard streams by default.
11298 *
11299 * If this happens, and the optional fd argument is not present,
11300 * the ioctl below will fail returning EBADF. This is what we want.
11301 */
11302
11303 if (!PyArg_ParseTuple(args, "|i", &fd))
11304 return NULL;
11305
11306#ifdef TERMSIZE_USE_IOCTL
11307 {
11308 struct winsize w;
11309 if (ioctl(fd, TIOCGWINSZ, &w))
11310 return PyErr_SetFromErrno(PyExc_OSError);
11311 columns = w.ws_col;
11312 lines = w.ws_row;
11313 }
11314#endif /* TERMSIZE_USE_IOCTL */
11315
11316#ifdef TERMSIZE_USE_CONIO
11317 {
11318 DWORD nhandle;
11319 HANDLE handle;
11320 CONSOLE_SCREEN_BUFFER_INFO csbi;
11321 switch (fd) {
11322 case 0: nhandle = STD_INPUT_HANDLE;
11323 break;
11324 case 1: nhandle = STD_OUTPUT_HANDLE;
11325 break;
11326 case 2: nhandle = STD_ERROR_HANDLE;
11327 break;
11328 default:
11329 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11330 }
11331 handle = GetStdHandle(nhandle);
11332 if (handle == NULL)
11333 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11334 if (handle == INVALID_HANDLE_VALUE)
11335 return PyErr_SetFromWindowsErr(0);
11336
11337 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11338 return PyErr_SetFromWindowsErr(0);
11339
11340 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11341 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11342 }
11343#endif /* TERMSIZE_USE_CONIO */
11344
11345 termsize = PyStructSequence_New(&TerminalSizeType);
11346 if (termsize == NULL)
11347 return NULL;
11348 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11349 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11350 if (PyErr_Occurred()) {
11351 Py_DECREF(termsize);
11352 return NULL;
11353 }
11354 return termsize;
11355}
11356#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11357
Larry Hastings2f936352014-08-05 14:04:04 +100011358
11359/*[clinic input]
11360os.cpu_count
11361
Charles-François Natali80d62e62015-08-13 20:37:08 +010011362Return the number of CPUs in the system; return None if indeterminable.
11363
11364This number is not equivalent to the number of CPUs the current process can
11365use. The number of usable CPUs can be obtained with
11366``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011367[clinic start generated code]*/
11368
Larry Hastings2f936352014-08-05 14:04:04 +100011369static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011370os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011371/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011372{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011373 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011374#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011375 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11376 Need to fallback to Vista behavior if this call isn't present */
11377 HINSTANCE hKernel32;
11378 hKernel32 = GetModuleHandleW(L"KERNEL32");
11379
11380 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11381 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11382 "GetMaximumProcessorCount");
11383 if (_GetMaximumProcessorCount != NULL) {
11384 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11385 }
11386 else {
11387 SYSTEM_INFO sysinfo;
11388 GetSystemInfo(&sysinfo);
11389 ncpu = sysinfo.dwNumberOfProcessors;
11390 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011391#elif defined(__hpux)
11392 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11393#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11394 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011395#elif defined(__DragonFly__) || \
11396 defined(__OpenBSD__) || \
11397 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011398 defined(__NetBSD__) || \
11399 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011400 int mib[2];
11401 size_t len = sizeof(ncpu);
11402 mib[0] = CTL_HW;
11403 mib[1] = HW_NCPU;
11404 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11405 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011406#endif
11407 if (ncpu >= 1)
11408 return PyLong_FromLong(ncpu);
11409 else
11410 Py_RETURN_NONE;
11411}
11412
Victor Stinnerdaf45552013-08-28 00:53:59 +020011413
Larry Hastings2f936352014-08-05 14:04:04 +100011414/*[clinic input]
11415os.get_inheritable -> bool
11416
11417 fd: int
11418 /
11419
11420Get the close-on-exe flag of the specified file descriptor.
11421[clinic start generated code]*/
11422
Larry Hastings2f936352014-08-05 14:04:04 +100011423static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011424os_get_inheritable_impl(PyObject *module, int fd)
11425/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011426{
Steve Dower8fc89802015-04-12 00:26:27 -040011427 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011428 _Py_BEGIN_SUPPRESS_IPH
11429 return_value = _Py_get_inheritable(fd);
11430 _Py_END_SUPPRESS_IPH
11431 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011432}
11433
11434
11435/*[clinic input]
11436os.set_inheritable
11437 fd: int
11438 inheritable: int
11439 /
11440
11441Set the inheritable flag of the specified file descriptor.
11442[clinic start generated code]*/
11443
Larry Hastings2f936352014-08-05 14:04:04 +100011444static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011445os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11446/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011447{
Steve Dower8fc89802015-04-12 00:26:27 -040011448 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011449
Steve Dower8fc89802015-04-12 00:26:27 -040011450 _Py_BEGIN_SUPPRESS_IPH
11451 result = _Py_set_inheritable(fd, inheritable, NULL);
11452 _Py_END_SUPPRESS_IPH
11453 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011454 return NULL;
11455 Py_RETURN_NONE;
11456}
11457
11458
11459#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011460/*[clinic input]
11461os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011462 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011463 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011464
Larry Hastings2f936352014-08-05 14:04:04 +100011465Get the close-on-exe flag of the specified file descriptor.
11466[clinic start generated code]*/
11467
Larry Hastings2f936352014-08-05 14:04:04 +100011468static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011469os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011470/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011471{
11472 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011473
11474 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11475 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011476 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011477 }
11478
Larry Hastings2f936352014-08-05 14:04:04 +100011479 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011480}
11481
Victor Stinnerdaf45552013-08-28 00:53:59 +020011482
Larry Hastings2f936352014-08-05 14:04:04 +100011483/*[clinic input]
11484os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011485 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011486 inheritable: bool
11487 /
11488
11489Set the inheritable flag of the specified handle.
11490[clinic start generated code]*/
11491
Larry Hastings2f936352014-08-05 14:04:04 +100011492static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011493os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011494 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011495/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011496{
11497 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011498 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11499 PyErr_SetFromWindowsErr(0);
11500 return NULL;
11501 }
11502 Py_RETURN_NONE;
11503}
Larry Hastings2f936352014-08-05 14:04:04 +100011504#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011505
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011506#ifndef MS_WINDOWS
11507PyDoc_STRVAR(get_blocking__doc__,
11508 "get_blocking(fd) -> bool\n" \
11509 "\n" \
11510 "Get the blocking mode of the file descriptor:\n" \
11511 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11512
11513static PyObject*
11514posix_get_blocking(PyObject *self, PyObject *args)
11515{
11516 int fd;
11517 int blocking;
11518
11519 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11520 return NULL;
11521
Steve Dower8fc89802015-04-12 00:26:27 -040011522 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011523 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011524 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011525 if (blocking < 0)
11526 return NULL;
11527 return PyBool_FromLong(blocking);
11528}
11529
11530PyDoc_STRVAR(set_blocking__doc__,
11531 "set_blocking(fd, blocking)\n" \
11532 "\n" \
11533 "Set the blocking mode of the specified file descriptor.\n" \
11534 "Set the O_NONBLOCK flag if blocking is False,\n" \
11535 "clear the O_NONBLOCK flag otherwise.");
11536
11537static PyObject*
11538posix_set_blocking(PyObject *self, PyObject *args)
11539{
Steve Dower8fc89802015-04-12 00:26:27 -040011540 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011541
11542 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11543 return NULL;
11544
Steve Dower8fc89802015-04-12 00:26:27 -040011545 _Py_BEGIN_SUPPRESS_IPH
11546 result = _Py_set_blocking(fd, blocking);
11547 _Py_END_SUPPRESS_IPH
11548 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011549 return NULL;
11550 Py_RETURN_NONE;
11551}
11552#endif /* !MS_WINDOWS */
11553
11554
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011555/*[clinic input]
11556class os.DirEntry "DirEntry *" "&DirEntryType"
11557[clinic start generated code]*/
11558/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011559
11560typedef struct {
11561 PyObject_HEAD
11562 PyObject *name;
11563 PyObject *path;
11564 PyObject *stat;
11565 PyObject *lstat;
11566#ifdef MS_WINDOWS
11567 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011568 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011569 int got_file_index;
11570#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011571#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011572 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011573#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011574 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011575 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011576#endif
11577} DirEntry;
11578
11579static void
11580DirEntry_dealloc(DirEntry *entry)
11581{
11582 Py_XDECREF(entry->name);
11583 Py_XDECREF(entry->path);
11584 Py_XDECREF(entry->stat);
11585 Py_XDECREF(entry->lstat);
11586 Py_TYPE(entry)->tp_free((PyObject *)entry);
11587}
11588
11589/* Forward reference */
11590static int
11591DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11592
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011593/*[clinic input]
11594os.DirEntry.is_symlink -> bool
11595
11596Return True if the entry is a symbolic link; cached per entry.
11597[clinic start generated code]*/
11598
Victor Stinner6036e442015-03-08 01:58:04 +010011599static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011600os_DirEntry_is_symlink_impl(DirEntry *self)
11601/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011602{
11603#ifdef MS_WINDOWS
11604 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011605#elif defined(HAVE_DIRENT_D_TYPE)
11606 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011607 if (self->d_type != DT_UNKNOWN)
11608 return self->d_type == DT_LNK;
11609 else
11610 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011611#else
11612 /* POSIX without d_type */
11613 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011614#endif
11615}
11616
11617static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011618DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11619{
11620 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011621 STRUCT_STAT st;
11622 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011623
11624#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011625 if (!PyUnicode_FSDecoder(self->path, &ub))
11626 return NULL;
11627 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011628#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011629 if (!PyUnicode_FSConverter(self->path, &ub))
11630 return NULL;
11631 const char *path = PyBytes_AS_STRING(ub);
11632 if (self->dir_fd != DEFAULT_DIR_FD) {
11633#ifdef HAVE_FSTATAT
11634 result = fstatat(self->dir_fd, path, &st,
11635 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11636#else
11637 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11638 return NULL;
11639#endif /* HAVE_FSTATAT */
11640 }
11641 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011642#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011643 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011644 if (follow_symlinks)
11645 result = STAT(path, &st);
11646 else
11647 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011648 }
11649 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011650
11651 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011652 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011653
11654 return _pystat_fromstructstat(&st);
11655}
11656
11657static PyObject *
11658DirEntry_get_lstat(DirEntry *self)
11659{
11660 if (!self->lstat) {
11661#ifdef MS_WINDOWS
11662 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11663#else /* POSIX */
11664 self->lstat = DirEntry_fetch_stat(self, 0);
11665#endif
11666 }
11667 Py_XINCREF(self->lstat);
11668 return self->lstat;
11669}
11670
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011671/*[clinic input]
11672os.DirEntry.stat
11673 *
11674 follow_symlinks: bool = True
11675
11676Return stat_result object for the entry; cached per entry.
11677[clinic start generated code]*/
11678
Victor Stinner6036e442015-03-08 01:58:04 +010011679static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011680os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11681/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011682{
11683 if (!follow_symlinks)
11684 return DirEntry_get_lstat(self);
11685
11686 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011687 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011688 if (result == -1)
11689 return NULL;
11690 else if (result)
11691 self->stat = DirEntry_fetch_stat(self, 1);
11692 else
11693 self->stat = DirEntry_get_lstat(self);
11694 }
11695
11696 Py_XINCREF(self->stat);
11697 return self->stat;
11698}
11699
Victor Stinner6036e442015-03-08 01:58:04 +010011700/* Set exception and return -1 on error, 0 for False, 1 for True */
11701static int
11702DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11703{
11704 PyObject *stat = NULL;
11705 PyObject *st_mode = NULL;
11706 long mode;
11707 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011708#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011709 int is_symlink;
11710 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011711#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011712#ifdef MS_WINDOWS
11713 unsigned long dir_bits;
11714#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011715 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011716
11717#ifdef MS_WINDOWS
11718 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11719 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011720#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011721 is_symlink = self->d_type == DT_LNK;
11722 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11723#endif
11724
Victor Stinner35a97c02015-03-08 02:59:09 +010011725#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011726 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011727#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011728 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011729 if (!stat) {
11730 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11731 /* If file doesn't exist (anymore), then return False
11732 (i.e., say it's not a file/directory) */
11733 PyErr_Clear();
11734 return 0;
11735 }
11736 goto error;
11737 }
11738 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11739 if (!st_mode)
11740 goto error;
11741
11742 mode = PyLong_AsLong(st_mode);
11743 if (mode == -1 && PyErr_Occurred())
11744 goto error;
11745 Py_CLEAR(st_mode);
11746 Py_CLEAR(stat);
11747 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011748#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011749 }
11750 else if (is_symlink) {
11751 assert(mode_bits != S_IFLNK);
11752 result = 0;
11753 }
11754 else {
11755 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11756#ifdef MS_WINDOWS
11757 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11758 if (mode_bits == S_IFDIR)
11759 result = dir_bits != 0;
11760 else
11761 result = dir_bits == 0;
11762#else /* POSIX */
11763 if (mode_bits == S_IFDIR)
11764 result = self->d_type == DT_DIR;
11765 else
11766 result = self->d_type == DT_REG;
11767#endif
11768 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011769#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011770
11771 return result;
11772
11773error:
11774 Py_XDECREF(st_mode);
11775 Py_XDECREF(stat);
11776 return -1;
11777}
11778
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011779/*[clinic input]
11780os.DirEntry.is_dir -> bool
11781 *
11782 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011783
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011784Return True if the entry is a directory; cached per entry.
11785[clinic start generated code]*/
11786
11787static int
11788os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11789/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11790{
11791 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011792}
11793
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011794/*[clinic input]
11795os.DirEntry.is_file -> bool
11796 *
11797 follow_symlinks: bool = True
11798
11799Return True if the entry is a file; cached per entry.
11800[clinic start generated code]*/
11801
11802static int
11803os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11804/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011805{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011806 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011807}
11808
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011809/*[clinic input]
11810os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011811
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011812Return inode of the entry; cached per entry.
11813[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011814
11815static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011816os_DirEntry_inode_impl(DirEntry *self)
11817/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011818{
11819#ifdef MS_WINDOWS
11820 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011821 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011822 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011823 STRUCT_STAT stat;
11824 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011825
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011826 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011827 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011828 path = PyUnicode_AsUnicode(unicode);
11829 result = LSTAT(path, &stat);
11830 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011831
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011832 if (result != 0)
11833 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011834
11835 self->win32_file_index = stat.st_ino;
11836 self->got_file_index = 1;
11837 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011838 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11839 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011840#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011841 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11842 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011843#endif
11844}
11845
11846static PyObject *
11847DirEntry_repr(DirEntry *self)
11848{
11849 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11850}
11851
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011852/*[clinic input]
11853os.DirEntry.__fspath__
11854
11855Returns the path for the entry.
11856[clinic start generated code]*/
11857
Brett Cannon96881cd2016-06-10 14:37:21 -070011858static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011859os_DirEntry___fspath___impl(DirEntry *self)
11860/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011861{
11862 Py_INCREF(self->path);
11863 return self->path;
11864}
11865
Victor Stinner6036e442015-03-08 01:58:04 +010011866static PyMemberDef DirEntry_members[] = {
11867 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11868 "the entry's base filename, relative to scandir() \"path\" argument"},
11869 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11870 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11871 {NULL}
11872};
11873
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011874#include "clinic/posixmodule.c.h"
11875
Victor Stinner6036e442015-03-08 01:58:04 +010011876static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011877 OS_DIRENTRY_IS_DIR_METHODDEF
11878 OS_DIRENTRY_IS_FILE_METHODDEF
11879 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11880 OS_DIRENTRY_STAT_METHODDEF
11881 OS_DIRENTRY_INODE_METHODDEF
11882 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011883 {NULL}
11884};
11885
Benjamin Peterson5646de42015-04-12 17:56:34 -040011886static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011887 PyVarObject_HEAD_INIT(NULL, 0)
11888 MODNAME ".DirEntry", /* tp_name */
11889 sizeof(DirEntry), /* tp_basicsize */
11890 0, /* tp_itemsize */
11891 /* methods */
11892 (destructor)DirEntry_dealloc, /* tp_dealloc */
11893 0, /* tp_print */
11894 0, /* tp_getattr */
11895 0, /* tp_setattr */
11896 0, /* tp_compare */
11897 (reprfunc)DirEntry_repr, /* tp_repr */
11898 0, /* tp_as_number */
11899 0, /* tp_as_sequence */
11900 0, /* tp_as_mapping */
11901 0, /* tp_hash */
11902 0, /* tp_call */
11903 0, /* tp_str */
11904 0, /* tp_getattro */
11905 0, /* tp_setattro */
11906 0, /* tp_as_buffer */
11907 Py_TPFLAGS_DEFAULT, /* tp_flags */
11908 0, /* tp_doc */
11909 0, /* tp_traverse */
11910 0, /* tp_clear */
11911 0, /* tp_richcompare */
11912 0, /* tp_weaklistoffset */
11913 0, /* tp_iter */
11914 0, /* tp_iternext */
11915 DirEntry_methods, /* tp_methods */
11916 DirEntry_members, /* tp_members */
11917};
11918
11919#ifdef MS_WINDOWS
11920
11921static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011922join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011923{
11924 Py_ssize_t path_len;
11925 Py_ssize_t size;
11926 wchar_t *result;
11927 wchar_t ch;
11928
11929 if (!path_wide) { /* Default arg: "." */
11930 path_wide = L".";
11931 path_len = 1;
11932 }
11933 else {
11934 path_len = wcslen(path_wide);
11935 }
11936
11937 /* The +1's are for the path separator and the NUL */
11938 size = path_len + 1 + wcslen(filename) + 1;
11939 result = PyMem_New(wchar_t, size);
11940 if (!result) {
11941 PyErr_NoMemory();
11942 return NULL;
11943 }
11944 wcscpy(result, path_wide);
11945 if (path_len > 0) {
11946 ch = result[path_len - 1];
11947 if (ch != SEP && ch != ALTSEP && ch != L':')
11948 result[path_len++] = SEP;
11949 wcscpy(result + path_len, filename);
11950 }
11951 return result;
11952}
11953
11954static PyObject *
11955DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11956{
11957 DirEntry *entry;
11958 BY_HANDLE_FILE_INFORMATION file_info;
11959 ULONG reparse_tag;
11960 wchar_t *joined_path;
11961
11962 entry = PyObject_New(DirEntry, &DirEntryType);
11963 if (!entry)
11964 return NULL;
11965 entry->name = NULL;
11966 entry->path = NULL;
11967 entry->stat = NULL;
11968 entry->lstat = NULL;
11969 entry->got_file_index = 0;
11970
11971 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11972 if (!entry->name)
11973 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011974 if (path->narrow) {
11975 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11976 if (!entry->name)
11977 goto error;
11978 }
Victor Stinner6036e442015-03-08 01:58:04 +010011979
11980 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11981 if (!joined_path)
11982 goto error;
11983
11984 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11985 PyMem_Free(joined_path);
11986 if (!entry->path)
11987 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011988 if (path->narrow) {
11989 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11990 if (!entry->path)
11991 goto error;
11992 }
Victor Stinner6036e442015-03-08 01:58:04 +010011993
Steve Dowercc16be82016-09-08 10:35:16 -070011994 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011995 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11996
11997 return (PyObject *)entry;
11998
11999error:
12000 Py_DECREF(entry);
12001 return NULL;
12002}
12003
12004#else /* POSIX */
12005
12006static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012007join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012008{
12009 Py_ssize_t path_len;
12010 Py_ssize_t size;
12011 char *result;
12012
12013 if (!path_narrow) { /* Default arg: "." */
12014 path_narrow = ".";
12015 path_len = 1;
12016 }
12017 else {
12018 path_len = strlen(path_narrow);
12019 }
12020
12021 if (filename_len == -1)
12022 filename_len = strlen(filename);
12023
12024 /* The +1's are for the path separator and the NUL */
12025 size = path_len + 1 + filename_len + 1;
12026 result = PyMem_New(char, size);
12027 if (!result) {
12028 PyErr_NoMemory();
12029 return NULL;
12030 }
12031 strcpy(result, path_narrow);
12032 if (path_len > 0 && result[path_len - 1] != '/')
12033 result[path_len++] = '/';
12034 strcpy(result + path_len, filename);
12035 return result;
12036}
12037
12038static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012039DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012040 ino_t d_ino
12041#ifdef HAVE_DIRENT_D_TYPE
12042 , unsigned char d_type
12043#endif
12044 )
Victor Stinner6036e442015-03-08 01:58:04 +010012045{
12046 DirEntry *entry;
12047 char *joined_path;
12048
12049 entry = PyObject_New(DirEntry, &DirEntryType);
12050 if (!entry)
12051 return NULL;
12052 entry->name = NULL;
12053 entry->path = NULL;
12054 entry->stat = NULL;
12055 entry->lstat = NULL;
12056
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012057 if (path->fd != -1) {
12058 entry->dir_fd = path->fd;
12059 joined_path = NULL;
12060 }
12061 else {
12062 entry->dir_fd = DEFAULT_DIR_FD;
12063 joined_path = join_path_filename(path->narrow, name, name_len);
12064 if (!joined_path)
12065 goto error;
12066 }
Victor Stinner6036e442015-03-08 01:58:04 +010012067
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012068 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012069 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012070 if (joined_path)
12071 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012072 }
12073 else {
12074 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012075 if (joined_path)
12076 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012077 }
12078 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012079 if (!entry->name)
12080 goto error;
12081
12082 if (path->fd != -1) {
12083 entry->path = entry->name;
12084 Py_INCREF(entry->path);
12085 }
12086 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012087 goto error;
12088
Victor Stinner35a97c02015-03-08 02:59:09 +010012089#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012090 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012091#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012092 entry->d_ino = d_ino;
12093
12094 return (PyObject *)entry;
12095
12096error:
12097 Py_XDECREF(entry);
12098 return NULL;
12099}
12100
12101#endif
12102
12103
12104typedef struct {
12105 PyObject_HEAD
12106 path_t path;
12107#ifdef MS_WINDOWS
12108 HANDLE handle;
12109 WIN32_FIND_DATAW file_data;
12110 int first_time;
12111#else /* POSIX */
12112 DIR *dirp;
12113#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012114#ifdef HAVE_FDOPENDIR
12115 int fd;
12116#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012117} ScandirIterator;
12118
12119#ifdef MS_WINDOWS
12120
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012121static int
12122ScandirIterator_is_closed(ScandirIterator *iterator)
12123{
12124 return iterator->handle == INVALID_HANDLE_VALUE;
12125}
12126
Victor Stinner6036e442015-03-08 01:58:04 +010012127static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012128ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012129{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012130 HANDLE handle = iterator->handle;
12131
12132 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012133 return;
12134
Victor Stinner6036e442015-03-08 01:58:04 +010012135 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012136 Py_BEGIN_ALLOW_THREADS
12137 FindClose(handle);
12138 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012139}
12140
12141static PyObject *
12142ScandirIterator_iternext(ScandirIterator *iterator)
12143{
12144 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12145 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012146 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012147
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012148 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012149 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012150 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012151
12152 while (1) {
12153 if (!iterator->first_time) {
12154 Py_BEGIN_ALLOW_THREADS
12155 success = FindNextFileW(iterator->handle, file_data);
12156 Py_END_ALLOW_THREADS
12157 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012158 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012159 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012160 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012161 break;
12162 }
12163 }
12164 iterator->first_time = 0;
12165
12166 /* Skip over . and .. */
12167 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012168 wcscmp(file_data->cFileName, L"..") != 0) {
12169 entry = DirEntry_from_find_data(&iterator->path, file_data);
12170 if (!entry)
12171 break;
12172 return entry;
12173 }
Victor Stinner6036e442015-03-08 01:58:04 +010012174
12175 /* Loop till we get a non-dot directory or finish iterating */
12176 }
12177
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012178 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012179 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012180 return NULL;
12181}
12182
12183#else /* POSIX */
12184
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012185static int
12186ScandirIterator_is_closed(ScandirIterator *iterator)
12187{
12188 return !iterator->dirp;
12189}
12190
Victor Stinner6036e442015-03-08 01:58:04 +010012191static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012192ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012193{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012194 DIR *dirp = iterator->dirp;
12195
12196 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012197 return;
12198
Victor Stinner6036e442015-03-08 01:58:04 +010012199 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012200 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012201#ifdef HAVE_FDOPENDIR
12202 if (iterator->path.fd != -1)
12203 rewinddir(dirp);
12204#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012205 closedir(dirp);
12206 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012207 return;
12208}
12209
12210static PyObject *
12211ScandirIterator_iternext(ScandirIterator *iterator)
12212{
12213 struct dirent *direntp;
12214 Py_ssize_t name_len;
12215 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012216 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012217
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012218 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012219 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012220 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012221
12222 while (1) {
12223 errno = 0;
12224 Py_BEGIN_ALLOW_THREADS
12225 direntp = readdir(iterator->dirp);
12226 Py_END_ALLOW_THREADS
12227
12228 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012229 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012230 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012231 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012232 break;
12233 }
12234
12235 /* Skip over . and .. */
12236 name_len = NAMLEN(direntp);
12237 is_dot = direntp->d_name[0] == '.' &&
12238 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12239 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012240 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012241 name_len, direntp->d_ino
12242#ifdef HAVE_DIRENT_D_TYPE
12243 , direntp->d_type
12244#endif
12245 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012246 if (!entry)
12247 break;
12248 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012249 }
12250
12251 /* Loop till we get a non-dot directory or finish iterating */
12252 }
12253
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012254 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012255 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012256 return NULL;
12257}
12258
12259#endif
12260
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012261static PyObject *
12262ScandirIterator_close(ScandirIterator *self, PyObject *args)
12263{
12264 ScandirIterator_closedir(self);
12265 Py_RETURN_NONE;
12266}
12267
12268static PyObject *
12269ScandirIterator_enter(PyObject *self, PyObject *args)
12270{
12271 Py_INCREF(self);
12272 return self;
12273}
12274
12275static PyObject *
12276ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12277{
12278 ScandirIterator_closedir(self);
12279 Py_RETURN_NONE;
12280}
12281
Victor Stinner6036e442015-03-08 01:58:04 +010012282static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012283ScandirIterator_finalize(ScandirIterator *iterator)
12284{
12285 PyObject *error_type, *error_value, *error_traceback;
12286
12287 /* Save the current exception, if any. */
12288 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12289
12290 if (!ScandirIterator_is_closed(iterator)) {
12291 ScandirIterator_closedir(iterator);
12292
12293 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12294 "unclosed scandir iterator %R", iterator)) {
12295 /* Spurious errors can appear at shutdown */
12296 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12297 PyErr_WriteUnraisable((PyObject *) iterator);
12298 }
12299 }
12300 }
12301
Victor Stinner7bfa4092016-03-23 00:43:54 +010012302 path_cleanup(&iterator->path);
12303
12304 /* Restore the saved exception. */
12305 PyErr_Restore(error_type, error_value, error_traceback);
12306}
12307
12308static void
Victor Stinner6036e442015-03-08 01:58:04 +010012309ScandirIterator_dealloc(ScandirIterator *iterator)
12310{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012311 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12312 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012313
Victor Stinner6036e442015-03-08 01:58:04 +010012314 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12315}
12316
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012317static PyMethodDef ScandirIterator_methods[] = {
12318 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12319 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12320 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12321 {NULL}
12322};
12323
Benjamin Peterson5646de42015-04-12 17:56:34 -040012324static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012325 PyVarObject_HEAD_INIT(NULL, 0)
12326 MODNAME ".ScandirIterator", /* tp_name */
12327 sizeof(ScandirIterator), /* tp_basicsize */
12328 0, /* tp_itemsize */
12329 /* methods */
12330 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12331 0, /* tp_print */
12332 0, /* tp_getattr */
12333 0, /* tp_setattr */
12334 0, /* tp_compare */
12335 0, /* tp_repr */
12336 0, /* tp_as_number */
12337 0, /* tp_as_sequence */
12338 0, /* tp_as_mapping */
12339 0, /* tp_hash */
12340 0, /* tp_call */
12341 0, /* tp_str */
12342 0, /* tp_getattro */
12343 0, /* tp_setattro */
12344 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012345 Py_TPFLAGS_DEFAULT
12346 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012347 0, /* tp_doc */
12348 0, /* tp_traverse */
12349 0, /* tp_clear */
12350 0, /* tp_richcompare */
12351 0, /* tp_weaklistoffset */
12352 PyObject_SelfIter, /* tp_iter */
12353 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012354 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012355 0, /* tp_members */
12356 0, /* tp_getset */
12357 0, /* tp_base */
12358 0, /* tp_dict */
12359 0, /* tp_descr_get */
12360 0, /* tp_descr_set */
12361 0, /* tp_dictoffset */
12362 0, /* tp_init */
12363 0, /* tp_alloc */
12364 0, /* tp_new */
12365 0, /* tp_free */
12366 0, /* tp_is_gc */
12367 0, /* tp_bases */
12368 0, /* tp_mro */
12369 0, /* tp_cache */
12370 0, /* tp_subclasses */
12371 0, /* tp_weaklist */
12372 0, /* tp_del */
12373 0, /* tp_version_tag */
12374 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012375};
12376
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012377/*[clinic input]
12378os.scandir
12379
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012380 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012381
12382Return an iterator of DirEntry objects for given path.
12383
BNMetrics08026b12018-11-02 17:56:25 +000012384path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012385is bytes, the names of yielded DirEntry objects will also be bytes; in
12386all other circumstances they will be str.
12387
12388If path is None, uses the path='.'.
12389[clinic start generated code]*/
12390
Victor Stinner6036e442015-03-08 01:58:04 +010012391static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012392os_scandir_impl(PyObject *module, path_t *path)
BNMetrics08026b12018-11-02 17:56:25 +000012393/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012394{
12395 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012396#ifdef MS_WINDOWS
12397 wchar_t *path_strW;
12398#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012399 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012400#ifdef HAVE_FDOPENDIR
12401 int fd = -1;
12402#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012403#endif
12404
12405 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12406 if (!iterator)
12407 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012408
12409#ifdef MS_WINDOWS
12410 iterator->handle = INVALID_HANDLE_VALUE;
12411#else
12412 iterator->dirp = NULL;
12413#endif
12414
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012415 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012416 /* Move the ownership to iterator->path */
12417 path->object = NULL;
12418 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012419
12420#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012421 iterator->first_time = 1;
12422
12423 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12424 if (!path_strW)
12425 goto error;
12426
12427 Py_BEGIN_ALLOW_THREADS
12428 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12429 Py_END_ALLOW_THREADS
12430
12431 PyMem_Free(path_strW);
12432
12433 if (iterator->handle == INVALID_HANDLE_VALUE) {
12434 path_error(&iterator->path);
12435 goto error;
12436 }
12437#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012438 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012439#ifdef HAVE_FDOPENDIR
12440 if (path->fd != -1) {
12441 /* closedir() closes the FD, so we duplicate it */
12442 fd = _Py_dup(path->fd);
12443 if (fd == -1)
12444 goto error;
12445
12446 Py_BEGIN_ALLOW_THREADS
12447 iterator->dirp = fdopendir(fd);
12448 Py_END_ALLOW_THREADS
12449 }
12450 else
12451#endif
12452 {
12453 if (iterator->path.narrow)
12454 path_str = iterator->path.narrow;
12455 else
12456 path_str = ".";
12457
12458 Py_BEGIN_ALLOW_THREADS
12459 iterator->dirp = opendir(path_str);
12460 Py_END_ALLOW_THREADS
12461 }
Victor Stinner6036e442015-03-08 01:58:04 +010012462
12463 if (!iterator->dirp) {
12464 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012465#ifdef HAVE_FDOPENDIR
12466 if (fd != -1) {
12467 Py_BEGIN_ALLOW_THREADS
12468 close(fd);
12469 Py_END_ALLOW_THREADS
12470 }
12471#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012472 goto error;
12473 }
12474#endif
12475
12476 return (PyObject *)iterator;
12477
12478error:
12479 Py_DECREF(iterator);
12480 return NULL;
12481}
12482
Ethan Furman410ef8e2016-06-04 12:06:26 -070012483/*
12484 Return the file system path representation of the object.
12485
12486 If the object is str or bytes, then allow it to pass through with
12487 an incremented refcount. If the object defines __fspath__(), then
12488 return the result of that method. All other types raise a TypeError.
12489*/
12490PyObject *
12491PyOS_FSPath(PyObject *path)
12492{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012493 /* For error message reasons, this function is manually inlined in
12494 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012495 _Py_IDENTIFIER(__fspath__);
12496 PyObject *func = NULL;
12497 PyObject *path_repr = NULL;
12498
12499 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12500 Py_INCREF(path);
12501 return path;
12502 }
12503
12504 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12505 if (NULL == func) {
12506 return PyErr_Format(PyExc_TypeError,
12507 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012508 "not %.200s",
12509 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012510 }
12511
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012512 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012513 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012514 if (NULL == path_repr) {
12515 return NULL;
12516 }
12517
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012518 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12519 PyErr_Format(PyExc_TypeError,
12520 "expected %.200s.__fspath__() to return str or bytes, "
12521 "not %.200s", Py_TYPE(path)->tp_name,
12522 Py_TYPE(path_repr)->tp_name);
12523 Py_DECREF(path_repr);
12524 return NULL;
12525 }
12526
Ethan Furman410ef8e2016-06-04 12:06:26 -070012527 return path_repr;
12528}
12529
12530/*[clinic input]
12531os.fspath
12532
12533 path: object
12534
12535Return the file system path representation of the object.
12536
Brett Cannonb4f43e92016-06-09 14:32:08 -070012537If the object is str or bytes, then allow it to pass through as-is. If the
12538object defines __fspath__(), then return the result of that method. All other
12539types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012540[clinic start generated code]*/
12541
12542static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012543os_fspath_impl(PyObject *module, PyObject *path)
12544/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012545{
12546 return PyOS_FSPath(path);
12547}
Victor Stinner6036e442015-03-08 01:58:04 +010012548
Victor Stinner9b1f4742016-09-06 16:18:52 -070012549#ifdef HAVE_GETRANDOM_SYSCALL
12550/*[clinic input]
12551os.getrandom
12552
12553 size: Py_ssize_t
12554 flags: int=0
12555
12556Obtain a series of random bytes.
12557[clinic start generated code]*/
12558
12559static PyObject *
12560os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12561/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12562{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012563 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012564 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012565
12566 if (size < 0) {
12567 errno = EINVAL;
12568 return posix_error();
12569 }
12570
Victor Stinnerec2319c2016-09-20 23:00:59 +020012571 bytes = PyBytes_FromStringAndSize(NULL, size);
12572 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012573 PyErr_NoMemory();
12574 return NULL;
12575 }
12576
12577 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012578 n = syscall(SYS_getrandom,
12579 PyBytes_AS_STRING(bytes),
12580 PyBytes_GET_SIZE(bytes),
12581 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012582 if (n < 0 && errno == EINTR) {
12583 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012584 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012585 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012586
12587 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012588 continue;
12589 }
12590 break;
12591 }
12592
12593 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012594 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012595 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012596 }
12597
Victor Stinnerec2319c2016-09-20 23:00:59 +020012598 if (n != size) {
12599 _PyBytes_Resize(&bytes, n);
12600 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012601
12602 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012603
12604error:
12605 Py_DECREF(bytes);
12606 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012607}
12608#endif /* HAVE_GETRANDOM_SYSCALL */
12609
Larry Hastings31826802013-10-19 00:09:25 -070012610
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012611static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012612
12613 OS_STAT_METHODDEF
12614 OS_ACCESS_METHODDEF
12615 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012616 OS_CHDIR_METHODDEF
12617 OS_CHFLAGS_METHODDEF
12618 OS_CHMOD_METHODDEF
12619 OS_FCHMOD_METHODDEF
12620 OS_LCHMOD_METHODDEF
12621 OS_CHOWN_METHODDEF
12622 OS_FCHOWN_METHODDEF
12623 OS_LCHOWN_METHODDEF
12624 OS_LCHFLAGS_METHODDEF
12625 OS_CHROOT_METHODDEF
12626 OS_CTERMID_METHODDEF
12627 OS_GETCWD_METHODDEF
12628 OS_GETCWDB_METHODDEF
12629 OS_LINK_METHODDEF
12630 OS_LISTDIR_METHODDEF
12631 OS_LSTAT_METHODDEF
12632 OS_MKDIR_METHODDEF
12633 OS_NICE_METHODDEF
12634 OS_GETPRIORITY_METHODDEF
12635 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012636#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012637 {"readlink", (PyCFunction)posix_readlink,
12638 METH_VARARGS | METH_KEYWORDS,
12639 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012640#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012641#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012642 {"readlink", (PyCFunction)win_readlink,
12643 METH_VARARGS | METH_KEYWORDS,
12644 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012645#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012646 OS_RENAME_METHODDEF
12647 OS_REPLACE_METHODDEF
12648 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012649 OS_SYMLINK_METHODDEF
12650 OS_SYSTEM_METHODDEF
12651 OS_UMASK_METHODDEF
12652 OS_UNAME_METHODDEF
12653 OS_UNLINK_METHODDEF
12654 OS_REMOVE_METHODDEF
12655 OS_UTIME_METHODDEF
12656 OS_TIMES_METHODDEF
12657 OS__EXIT_METHODDEF
12658 OS_EXECV_METHODDEF
12659 OS_EXECVE_METHODDEF
12660 OS_SPAWNV_METHODDEF
12661 OS_SPAWNVE_METHODDEF
12662 OS_FORK1_METHODDEF
12663 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012664 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012665 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12666 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12667 OS_SCHED_GETPARAM_METHODDEF
12668 OS_SCHED_GETSCHEDULER_METHODDEF
12669 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12670 OS_SCHED_SETPARAM_METHODDEF
12671 OS_SCHED_SETSCHEDULER_METHODDEF
12672 OS_SCHED_YIELD_METHODDEF
12673 OS_SCHED_SETAFFINITY_METHODDEF
12674 OS_SCHED_GETAFFINITY_METHODDEF
12675 OS_OPENPTY_METHODDEF
12676 OS_FORKPTY_METHODDEF
12677 OS_GETEGID_METHODDEF
12678 OS_GETEUID_METHODDEF
12679 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012680#ifdef HAVE_GETGROUPLIST
12681 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12682#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012683 OS_GETGROUPS_METHODDEF
12684 OS_GETPID_METHODDEF
12685 OS_GETPGRP_METHODDEF
12686 OS_GETPPID_METHODDEF
12687 OS_GETUID_METHODDEF
12688 OS_GETLOGIN_METHODDEF
12689 OS_KILL_METHODDEF
12690 OS_KILLPG_METHODDEF
12691 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012692#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012693 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012694#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012695 OS_SETUID_METHODDEF
12696 OS_SETEUID_METHODDEF
12697 OS_SETREUID_METHODDEF
12698 OS_SETGID_METHODDEF
12699 OS_SETEGID_METHODDEF
12700 OS_SETREGID_METHODDEF
12701 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012702#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012703 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012704#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012705 OS_GETPGID_METHODDEF
12706 OS_SETPGRP_METHODDEF
12707 OS_WAIT_METHODDEF
12708 OS_WAIT3_METHODDEF
12709 OS_WAIT4_METHODDEF
12710 OS_WAITID_METHODDEF
12711 OS_WAITPID_METHODDEF
12712 OS_GETSID_METHODDEF
12713 OS_SETSID_METHODDEF
12714 OS_SETPGID_METHODDEF
12715 OS_TCGETPGRP_METHODDEF
12716 OS_TCSETPGRP_METHODDEF
12717 OS_OPEN_METHODDEF
12718 OS_CLOSE_METHODDEF
12719 OS_CLOSERANGE_METHODDEF
12720 OS_DEVICE_ENCODING_METHODDEF
12721 OS_DUP_METHODDEF
12722 OS_DUP2_METHODDEF
12723 OS_LOCKF_METHODDEF
12724 OS_LSEEK_METHODDEF
12725 OS_READ_METHODDEF
12726 OS_READV_METHODDEF
12727 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012728 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012729 OS_WRITE_METHODDEF
12730 OS_WRITEV_METHODDEF
12731 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012732 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012733#ifdef HAVE_SENDFILE
12734 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12735 posix_sendfile__doc__},
12736#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012737 OS_FSTAT_METHODDEF
12738 OS_ISATTY_METHODDEF
12739 OS_PIPE_METHODDEF
12740 OS_PIPE2_METHODDEF
12741 OS_MKFIFO_METHODDEF
12742 OS_MKNOD_METHODDEF
12743 OS_MAJOR_METHODDEF
12744 OS_MINOR_METHODDEF
12745 OS_MAKEDEV_METHODDEF
12746 OS_FTRUNCATE_METHODDEF
12747 OS_TRUNCATE_METHODDEF
12748 OS_POSIX_FALLOCATE_METHODDEF
12749 OS_POSIX_FADVISE_METHODDEF
12750 OS_PUTENV_METHODDEF
12751 OS_UNSETENV_METHODDEF
12752 OS_STRERROR_METHODDEF
12753 OS_FCHDIR_METHODDEF
12754 OS_FSYNC_METHODDEF
12755 OS_SYNC_METHODDEF
12756 OS_FDATASYNC_METHODDEF
12757 OS_WCOREDUMP_METHODDEF
12758 OS_WIFCONTINUED_METHODDEF
12759 OS_WIFSTOPPED_METHODDEF
12760 OS_WIFSIGNALED_METHODDEF
12761 OS_WIFEXITED_METHODDEF
12762 OS_WEXITSTATUS_METHODDEF
12763 OS_WTERMSIG_METHODDEF
12764 OS_WSTOPSIG_METHODDEF
12765 OS_FSTATVFS_METHODDEF
12766 OS_STATVFS_METHODDEF
12767 OS_CONFSTR_METHODDEF
12768 OS_SYSCONF_METHODDEF
12769 OS_FPATHCONF_METHODDEF
12770 OS_PATHCONF_METHODDEF
12771 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012772 OS__GETFULLPATHNAME_METHODDEF
12773 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012774 OS__GETDISKUSAGE_METHODDEF
12775 OS__GETFINALPATHNAME_METHODDEF
12776 OS__GETVOLUMEPATHNAME_METHODDEF
12777 OS_GETLOADAVG_METHODDEF
12778 OS_URANDOM_METHODDEF
12779 OS_SETRESUID_METHODDEF
12780 OS_SETRESGID_METHODDEF
12781 OS_GETRESUID_METHODDEF
12782 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012783
Larry Hastings2f936352014-08-05 14:04:04 +100012784 OS_GETXATTR_METHODDEF
12785 OS_SETXATTR_METHODDEF
12786 OS_REMOVEXATTR_METHODDEF
12787 OS_LISTXATTR_METHODDEF
12788
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012789#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12790 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12791#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012792 OS_CPU_COUNT_METHODDEF
12793 OS_GET_INHERITABLE_METHODDEF
12794 OS_SET_INHERITABLE_METHODDEF
12795 OS_GET_HANDLE_INHERITABLE_METHODDEF
12796 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012797#ifndef MS_WINDOWS
12798 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12799 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12800#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012801 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012802 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012803 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012804 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012805};
12806
12807
Brian Curtin52173d42010-12-02 18:29:18 +000012808#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012809static int
Brian Curtin52173d42010-12-02 18:29:18 +000012810enable_symlink()
12811{
12812 HANDLE tok;
12813 TOKEN_PRIVILEGES tok_priv;
12814 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012815
12816 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012817 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012818
12819 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012820 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012821
12822 tok_priv.PrivilegeCount = 1;
12823 tok_priv.Privileges[0].Luid = luid;
12824 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12825
12826 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12827 sizeof(TOKEN_PRIVILEGES),
12828 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012829 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012830
Brian Curtin3b4499c2010-12-28 14:31:47 +000012831 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12832 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012833}
12834#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12835
Barry Warsaw4a342091996-12-19 23:50:02 +000012836static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012837all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012838{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012839#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012840 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012841#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012842#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012843 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012844#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012845#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012846 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012847#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012848#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012849 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012850#endif
Fred Drakec9680921999-12-13 16:37:25 +000012851#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012852 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012853#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012854#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012855 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012856#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012857#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012858 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012859#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012860#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012861 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012862#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012863#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012864 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012865#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012866#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012867 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012868#endif
12869#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012870 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012871#endif
12872#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012873 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012874#endif
12875#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012876 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012877#endif
12878#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012879 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012880#endif
12881#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012882 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012883#endif
12884#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012885 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012886#endif
12887#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012888 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012889#endif
12890#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012891 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012892#endif
12893#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012894 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012895#endif
12896#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012897 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012898#endif
12899#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012900 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012901#endif
12902#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012903 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012904#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012905#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012906 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012907#endif
12908#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012909 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012910#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012911#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012912 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012913#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012914#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012915 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012916#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012917#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012918#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012919 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012920#endif
12921#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012922 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012923#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012924#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012925#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012926 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012927#endif
12928#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012929 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012930#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012931#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012932 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012933#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012934#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012935 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012936#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012937#ifdef O_TMPFILE
12938 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12939#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012940#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012941 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012942#endif
12943#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012944 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012945#endif
12946#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012947 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012948#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012949#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012950 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012951#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012952#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012953 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012954#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012955
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012956
Jesus Cea94363612012-06-22 18:32:07 +020012957#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012958 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012959#endif
12960#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012961 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012962#endif
12963
Tim Peters5aa91602002-01-30 05:46:57 +000012964/* MS Windows */
12965#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012966 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012967 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012968#endif
12969#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012970 /* Optimize for short life (keep in memory). */
12971 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012972 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012973#endif
12974#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012975 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012976 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012977#endif
12978#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012979 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012980 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012981#endif
12982#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012983 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012984 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012985#endif
12986
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012987/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012988#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012989 /* Send a SIGIO signal whenever input or output
12990 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012991 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012992#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012993#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012994 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012995 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012996#endif
12997#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012998 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012999 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013000#endif
13001#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013002 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013003 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013004#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013005#ifdef O_NOLINKS
13006 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013007 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013008#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013009#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013010 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013011 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013012#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013013
Victor Stinner8c62be82010-05-06 00:08:46 +000013014 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013015#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013016 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013017#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013018#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013019 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013020#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013021#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013022 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013023#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013024#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013025 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013026#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013027#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013028 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013029#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013030#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013031 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013032#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013033#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013034 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013035#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013036#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013037 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013038#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013039#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013040 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013041#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013042#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013043 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013044#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013045#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013046 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013047#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013048#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013049 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013050#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013051#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013052 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013053#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013054#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013055 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013056#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013057#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013058 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013059#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013060#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013061 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013062#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013063#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013064 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013065#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013066
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013067 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013068#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013069 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013070#endif /* ST_RDONLY */
13071#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013072 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013073#endif /* ST_NOSUID */
13074
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013075 /* GNU extensions */
13076#ifdef ST_NODEV
13077 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13078#endif /* ST_NODEV */
13079#ifdef ST_NOEXEC
13080 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13081#endif /* ST_NOEXEC */
13082#ifdef ST_SYNCHRONOUS
13083 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13084#endif /* ST_SYNCHRONOUS */
13085#ifdef ST_MANDLOCK
13086 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13087#endif /* ST_MANDLOCK */
13088#ifdef ST_WRITE
13089 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13090#endif /* ST_WRITE */
13091#ifdef ST_APPEND
13092 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13093#endif /* ST_APPEND */
13094#ifdef ST_NOATIME
13095 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13096#endif /* ST_NOATIME */
13097#ifdef ST_NODIRATIME
13098 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13099#endif /* ST_NODIRATIME */
13100#ifdef ST_RELATIME
13101 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13102#endif /* ST_RELATIME */
13103
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013104 /* FreeBSD sendfile() constants */
13105#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013106 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013107#endif
13108#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013109 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013110#endif
13111#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013112 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013113#endif
13114
Ross Lagerwall7807c352011-03-17 20:20:30 +020013115 /* constants for posix_fadvise */
13116#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013117 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013118#endif
13119#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013120 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013121#endif
13122#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013123 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013124#endif
13125#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013126 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013127#endif
13128#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013129 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013130#endif
13131#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013132 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013133#endif
13134
13135 /* constants for waitid */
13136#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013137 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13138 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13139 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013140#endif
13141#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013142 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013143#endif
13144#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013145 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013146#endif
13147#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013148 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013149#endif
13150#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013151 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013152#endif
13153#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013154 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013155#endif
13156#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013157 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013158#endif
13159#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013160 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013161#endif
13162
13163 /* constants for lockf */
13164#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013165 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013166#endif
13167#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013168 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013169#endif
13170#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013171 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013172#endif
13173#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013174 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013175#endif
13176
Pablo Galindo4defba32018-01-27 16:16:37 +000013177#ifdef RWF_DSYNC
13178 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13179#endif
13180#ifdef RWF_HIPRI
13181 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13182#endif
13183#ifdef RWF_SYNC
13184 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13185#endif
13186#ifdef RWF_NOWAIT
13187 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13188#endif
13189
Guido van Rossum246bc171999-02-01 23:54:31 +000013190#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013191 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13192 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13193 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13194 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13195 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013196#endif
13197
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013198#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013199#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013200 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013201#endif
13202#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013203 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013204#endif
13205#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013206 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013207#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013208#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013209 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013210#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013211#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013212 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013213#endif
13214#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013215 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013216#endif
13217#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013218 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013219#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013220#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013221 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013222#endif
13223#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013224 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013225#endif
13226#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013227 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013228#endif
13229#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013230 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013231#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013232#endif
13233
Benjamin Peterson9428d532011-09-14 11:45:52 -040013234#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013235 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13236 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13237 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013238#endif
13239
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013240#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013241 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013242#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013243#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013244 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013245#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013246#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013247 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013248#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013249#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013250 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013251#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013252#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013253 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013254#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013255#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013256 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013257#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013258#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013259 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013260#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013261#if HAVE_DECL_RTLD_MEMBER
13262 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13263#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013264
Victor Stinner9b1f4742016-09-06 16:18:52 -070013265#ifdef HAVE_GETRANDOM_SYSCALL
13266 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13267 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13268#endif
13269
Victor Stinner8c62be82010-05-06 00:08:46 +000013270 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013271}
13272
13273
Martin v. Löwis1a214512008-06-11 05:26:20 +000013274static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013275 PyModuleDef_HEAD_INIT,
13276 MODNAME,
13277 posix__doc__,
13278 -1,
13279 posix_methods,
13280 NULL,
13281 NULL,
13282 NULL,
13283 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013284};
13285
13286
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013287static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013288
13289#ifdef HAVE_FACCESSAT
13290 "HAVE_FACCESSAT",
13291#endif
13292
13293#ifdef HAVE_FCHDIR
13294 "HAVE_FCHDIR",
13295#endif
13296
13297#ifdef HAVE_FCHMOD
13298 "HAVE_FCHMOD",
13299#endif
13300
13301#ifdef HAVE_FCHMODAT
13302 "HAVE_FCHMODAT",
13303#endif
13304
13305#ifdef HAVE_FCHOWN
13306 "HAVE_FCHOWN",
13307#endif
13308
Larry Hastings00964ed2013-08-12 13:49:30 -040013309#ifdef HAVE_FCHOWNAT
13310 "HAVE_FCHOWNAT",
13311#endif
13312
Larry Hastings9cf065c2012-06-22 16:30:09 -070013313#ifdef HAVE_FEXECVE
13314 "HAVE_FEXECVE",
13315#endif
13316
13317#ifdef HAVE_FDOPENDIR
13318 "HAVE_FDOPENDIR",
13319#endif
13320
Georg Brandl306336b2012-06-24 12:55:33 +020013321#ifdef HAVE_FPATHCONF
13322 "HAVE_FPATHCONF",
13323#endif
13324
Larry Hastings9cf065c2012-06-22 16:30:09 -070013325#ifdef HAVE_FSTATAT
13326 "HAVE_FSTATAT",
13327#endif
13328
13329#ifdef HAVE_FSTATVFS
13330 "HAVE_FSTATVFS",
13331#endif
13332
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013333#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013334 "HAVE_FTRUNCATE",
13335#endif
13336
Larry Hastings9cf065c2012-06-22 16:30:09 -070013337#ifdef HAVE_FUTIMENS
13338 "HAVE_FUTIMENS",
13339#endif
13340
13341#ifdef HAVE_FUTIMES
13342 "HAVE_FUTIMES",
13343#endif
13344
13345#ifdef HAVE_FUTIMESAT
13346 "HAVE_FUTIMESAT",
13347#endif
13348
13349#ifdef HAVE_LINKAT
13350 "HAVE_LINKAT",
13351#endif
13352
13353#ifdef HAVE_LCHFLAGS
13354 "HAVE_LCHFLAGS",
13355#endif
13356
13357#ifdef HAVE_LCHMOD
13358 "HAVE_LCHMOD",
13359#endif
13360
13361#ifdef HAVE_LCHOWN
13362 "HAVE_LCHOWN",
13363#endif
13364
13365#ifdef HAVE_LSTAT
13366 "HAVE_LSTAT",
13367#endif
13368
13369#ifdef HAVE_LUTIMES
13370 "HAVE_LUTIMES",
13371#endif
13372
13373#ifdef HAVE_MKDIRAT
13374 "HAVE_MKDIRAT",
13375#endif
13376
13377#ifdef HAVE_MKFIFOAT
13378 "HAVE_MKFIFOAT",
13379#endif
13380
13381#ifdef HAVE_MKNODAT
13382 "HAVE_MKNODAT",
13383#endif
13384
13385#ifdef HAVE_OPENAT
13386 "HAVE_OPENAT",
13387#endif
13388
13389#ifdef HAVE_READLINKAT
13390 "HAVE_READLINKAT",
13391#endif
13392
13393#ifdef HAVE_RENAMEAT
13394 "HAVE_RENAMEAT",
13395#endif
13396
13397#ifdef HAVE_SYMLINKAT
13398 "HAVE_SYMLINKAT",
13399#endif
13400
13401#ifdef HAVE_UNLINKAT
13402 "HAVE_UNLINKAT",
13403#endif
13404
13405#ifdef HAVE_UTIMENSAT
13406 "HAVE_UTIMENSAT",
13407#endif
13408
13409#ifdef MS_WINDOWS
13410 "MS_WINDOWS",
13411#endif
13412
13413 NULL
13414};
13415
13416
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013417PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013418INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013419{
Victor Stinner8c62be82010-05-06 00:08:46 +000013420 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013421 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013422 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013423
Brian Curtin52173d42010-12-02 18:29:18 +000013424#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013425 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013426#endif
13427
Victor Stinner8c62be82010-05-06 00:08:46 +000013428 m = PyModule_Create(&posixmodule);
13429 if (m == NULL)
13430 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013431
Victor Stinner8c62be82010-05-06 00:08:46 +000013432 /* Initialize environ dictionary */
13433 v = convertenviron();
13434 Py_XINCREF(v);
13435 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13436 return NULL;
13437 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013438
Victor Stinner8c62be82010-05-06 00:08:46 +000013439 if (all_ins(m))
13440 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013441
Victor Stinner8c62be82010-05-06 00:08:46 +000013442 if (setup_confname_tables(m))
13443 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013444
Victor Stinner8c62be82010-05-06 00:08:46 +000013445 Py_INCREF(PyExc_OSError);
13446 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013447
Guido van Rossumb3d39562000-01-31 18:41:26 +000013448#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013449 if (posix_putenv_garbage == NULL)
13450 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013451#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013452
Victor Stinner8c62be82010-05-06 00:08:46 +000013453 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013454#if defined(HAVE_WAITID) && !defined(__APPLE__)
13455 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013456 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13457 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013458#endif
13459
Christian Heimes25827622013-10-12 01:27:08 +020013460 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013461 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13462 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13463 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013464 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13465 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013466 structseq_new = StatResultType.tp_new;
13467 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013468
Christian Heimes25827622013-10-12 01:27:08 +020013469 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013470 if (PyStructSequence_InitType2(&StatVFSResultType,
13471 &statvfs_result_desc) < 0)
13472 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013473#ifdef NEED_TICKS_PER_SECOND
13474# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013475 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013476# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013477 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013478# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013479 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013480# endif
13481#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013482
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013483#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013484 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013485 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13486 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013487 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013488#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013489
13490 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013491 if (PyStructSequence_InitType2(&TerminalSizeType,
13492 &TerminalSize_desc) < 0)
13493 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013494
13495 /* initialize scandir types */
13496 if (PyType_Ready(&ScandirIteratorType) < 0)
13497 return NULL;
13498 if (PyType_Ready(&DirEntryType) < 0)
13499 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013500 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013501#if defined(HAVE_WAITID) && !defined(__APPLE__)
13502 Py_INCREF((PyObject*) &WaitidResultType);
13503 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13504#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013505 Py_INCREF((PyObject*) &StatResultType);
13506 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13507 Py_INCREF((PyObject*) &StatVFSResultType);
13508 PyModule_AddObject(m, "statvfs_result",
13509 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013510
13511#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013512 Py_INCREF(&SchedParamType);
13513 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013514#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013515
Larry Hastings605a62d2012-06-24 04:33:36 -070013516 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013517 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13518 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013519 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13520
13521 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013522 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13523 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013524 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13525
Thomas Wouters477c8d52006-05-27 19:21:47 +000013526#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013527 /*
13528 * Step 2 of weak-linking support on Mac OS X.
13529 *
13530 * The code below removes functions that are not available on the
13531 * currently active platform.
13532 *
13533 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013534 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013535 * OSX 10.4.
13536 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013537#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013538 if (fstatvfs == NULL) {
13539 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13540 return NULL;
13541 }
13542 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013543#endif /* HAVE_FSTATVFS */
13544
13545#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013546 if (statvfs == NULL) {
13547 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13548 return NULL;
13549 }
13550 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013551#endif /* HAVE_STATVFS */
13552
13553# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013554 if (lchown == NULL) {
13555 if (PyObject_DelAttrString(m, "lchown") == -1) {
13556 return NULL;
13557 }
13558 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013559#endif /* HAVE_LCHOWN */
13560
13561
13562#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013563
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013564 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013565 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13566
Larry Hastings6fe20b32012-04-19 15:07:49 -070013567 billion = PyLong_FromLong(1000000000);
13568 if (!billion)
13569 return NULL;
13570
Larry Hastings9cf065c2012-06-22 16:30:09 -070013571 /* suppress "function not used" warnings */
13572 {
13573 int ignored;
13574 fd_specified("", -1);
13575 follow_symlinks_specified("", 1);
13576 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13577 dir_fd_converter(Py_None, &ignored);
13578 dir_fd_unavailable(Py_None, &ignored);
13579 }
13580
13581 /*
13582 * provide list of locally available functions
13583 * so os.py can populate support_* lists
13584 */
13585 list = PyList_New(0);
13586 if (!list)
13587 return NULL;
13588 for (trace = have_functions; *trace; trace++) {
13589 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13590 if (!unicode)
13591 return NULL;
13592 if (PyList_Append(list, unicode))
13593 return NULL;
13594 Py_DECREF(unicode);
13595 }
13596 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013597
13598 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013599 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013600
13601 initialized = 1;
13602
Victor Stinner8c62be82010-05-06 00:08:46 +000013603 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013604}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013605
13606#ifdef __cplusplus
13607}
13608#endif