blob: dbd534cab06a66eba68e7858c76deeee3528d94f [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 Hastings9cf065c2012-06-22 16:30:09 -07004648 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004649 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004650
Christian Heimesb3c87242013-08-01 00:08:16 +02004651 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004652
Larry Hastings9cf065c2012-06-22 16:30:09 -07004653 if (times && (times != Py_None) && ns) {
4654 PyErr_SetString(PyExc_ValueError,
4655 "utime: you may specify either 'times'"
4656 " or 'ns' but not both");
4657 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004658 }
4659
4660 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004661 time_t a_sec, m_sec;
4662 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004663 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004664 PyErr_SetString(PyExc_TypeError,
4665 "utime: 'times' must be either"
4666 " a tuple of two ints or None");
4667 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004668 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004669 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004670 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004671 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004672 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004673 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004674 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004675 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004676 utime.atime_s = a_sec;
4677 utime.atime_ns = a_nsec;
4678 utime.mtime_s = m_sec;
4679 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004680 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004681 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004682 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004683 PyErr_SetString(PyExc_TypeError,
4684 "utime: 'ns' must be a tuple of two ints");
4685 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004686 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004687 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004688 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004689 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004690 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004691 &utime.mtime_s, &utime.mtime_ns)) {
4692 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004693 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004694 }
4695 else {
4696 /* times and ns are both None/unspecified. use "now". */
4697 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004698 }
4699
Victor Stinner4552ced2015-09-21 22:37:15 +02004700#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004701 if (follow_symlinks_specified("utime", follow_symlinks))
4702 goto exit;
4703#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004704
Larry Hastings2f936352014-08-05 14:04:04 +10004705 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4706 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4707 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004709
Larry Hastings9cf065c2012-06-22 16:30:09 -07004710#if !defined(HAVE_UTIMENSAT)
4711 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004712 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713 "utime: cannot use dir_fd and follow_symlinks "
4714 "together on this platform");
4715 goto exit;
4716 }
4717#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004718
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004719#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004721 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4722 NULL, OPEN_EXISTING,
4723 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004724 Py_END_ALLOW_THREADS
4725 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004726 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004728 }
4729
Larry Hastings9cf065c2012-06-22 16:30:09 -07004730 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004731 GetSystemTimeAsFileTime(&mtime);
4732 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004733 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004734 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004735 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4736 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004737 }
4738 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4739 /* Avoid putting the file name into the error here,
4740 as that may confuse the user into believing that
4741 something is wrong with the file, when it also
4742 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004743 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004745 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004746#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004748
Victor Stinner4552ced2015-09-21 22:37:15 +02004749#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004751 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004752 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004753#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004754
Victor Stinner528a9ab2015-09-03 21:30:26 +02004755#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004757 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 else
4759#endif
4760
Victor Stinner528a9ab2015-09-03 21:30:26 +02004761#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004762 if (path->fd != -1)
4763 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004764 else
4765#endif
4766
Larry Hastings2f936352014-08-05 14:04:04 +10004767 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004768
4769 Py_END_ALLOW_THREADS
4770
4771 if (result < 0) {
4772 /* see previous comment about not putting filename in error here */
4773 return_value = posix_error();
4774 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004775 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004776
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004777#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004778
4779 Py_INCREF(Py_None);
4780 return_value = Py_None;
4781
4782exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004783#ifdef MS_WINDOWS
4784 if (hFile != INVALID_HANDLE_VALUE)
4785 CloseHandle(hFile);
4786#endif
4787 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004788}
4789
Guido van Rossum3b066191991-06-04 19:40:25 +00004790/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004791
Larry Hastings2f936352014-08-05 14:04:04 +10004792
4793/*[clinic input]
4794os._exit
4795
4796 status: int
4797
4798Exit to the system with specified status, without normal exit processing.
4799[clinic start generated code]*/
4800
Larry Hastings2f936352014-08-05 14:04:04 +10004801static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004802os__exit_impl(PyObject *module, int status)
4803/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004804{
4805 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004806 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004807}
4808
Steve Dowercc16be82016-09-08 10:35:16 -07004809#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4810#define EXECV_CHAR wchar_t
4811#else
4812#define EXECV_CHAR char
4813#endif
4814
Martin v. Löwis114619e2002-10-07 06:44:21 +00004815#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4816static void
Steve Dowercc16be82016-09-08 10:35:16 -07004817free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004818{
Victor Stinner8c62be82010-05-06 00:08:46 +00004819 Py_ssize_t i;
4820 for (i = 0; i < count; i++)
4821 PyMem_Free(array[i]);
4822 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004823}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004824
Berker Peksag81816462016-09-15 20:19:47 +03004825static int
4826fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004827{
Victor Stinner8c62be82010-05-06 00:08:46 +00004828 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004829 PyObject *ub;
4830 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004831#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004832 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004833 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004834 *out = PyUnicode_AsWideCharString(ub, &size);
4835 if (*out)
4836 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004837#else
Berker Peksag81816462016-09-15 20:19:47 +03004838 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004839 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004840 size = PyBytes_GET_SIZE(ub);
4841 *out = PyMem_Malloc(size + 1);
4842 if (*out) {
4843 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4844 result = 1;
4845 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004846 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004847#endif
Berker Peksag81816462016-09-15 20:19:47 +03004848 Py_DECREF(ub);
4849 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004850}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004851#endif
4852
Ross Lagerwall7807c352011-03-17 20:20:30 +02004853#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004854static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004855parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4856{
Victor Stinner8c62be82010-05-06 00:08:46 +00004857 Py_ssize_t i, pos, envc;
4858 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004859 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004860 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004861
Victor Stinner8c62be82010-05-06 00:08:46 +00004862 i = PyMapping_Size(env);
4863 if (i < 0)
4864 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004865 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004866 if (envlist == NULL) {
4867 PyErr_NoMemory();
4868 return NULL;
4869 }
4870 envc = 0;
4871 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004872 if (!keys)
4873 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004874 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004875 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004876 goto error;
4877 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4878 PyErr_Format(PyExc_TypeError,
4879 "env.keys() or env.values() is not a list");
4880 goto error;
4881 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004882
Victor Stinner8c62be82010-05-06 00:08:46 +00004883 for (pos = 0; pos < i; pos++) {
4884 key = PyList_GetItem(keys, pos);
4885 val = PyList_GetItem(vals, pos);
4886 if (!key || !val)
4887 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004888
Berker Peksag81816462016-09-15 20:19:47 +03004889#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4890 if (!PyUnicode_FSDecoder(key, &key2))
4891 goto error;
4892 if (!PyUnicode_FSDecoder(val, &val2)) {
4893 Py_DECREF(key2);
4894 goto error;
4895 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004896 /* Search from index 1 because on Windows starting '=' is allowed for
4897 defining hidden environment variables. */
4898 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4899 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4900 {
4901 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004902 Py_DECREF(key2);
4903 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004904 goto error;
4905 }
Berker Peksag81816462016-09-15 20:19:47 +03004906 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4907#else
4908 if (!PyUnicode_FSConverter(key, &key2))
4909 goto error;
4910 if (!PyUnicode_FSConverter(val, &val2)) {
4911 Py_DECREF(key2);
4912 goto error;
4913 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004914 if (PyBytes_GET_SIZE(key2) == 0 ||
4915 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4916 {
4917 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004918 Py_DECREF(key2);
4919 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004920 goto error;
4921 }
Berker Peksag81816462016-09-15 20:19:47 +03004922 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4923 PyBytes_AS_STRING(val2));
4924#endif
4925 Py_DECREF(key2);
4926 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004927 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004929
4930 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4931 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004932 goto error;
4933 }
Berker Peksag81816462016-09-15 20:19:47 +03004934
Steve Dowercc16be82016-09-08 10:35:16 -07004935 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 }
4937 Py_DECREF(vals);
4938 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004939
Victor Stinner8c62be82010-05-06 00:08:46 +00004940 envlist[envc] = 0;
4941 *envc_ptr = envc;
4942 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004943
4944error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 Py_XDECREF(keys);
4946 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004947 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004949}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004950
Steve Dowercc16be82016-09-08 10:35:16 -07004951static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004952parse_arglist(PyObject* argv, Py_ssize_t *argc)
4953{
4954 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004955 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004956 if (argvlist == NULL) {
4957 PyErr_NoMemory();
4958 return NULL;
4959 }
4960 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004961 PyObject* item = PySequence_ITEM(argv, i);
4962 if (item == NULL)
4963 goto fail;
4964 if (!fsconvert_strdup(item, &argvlist[i])) {
4965 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004966 goto fail;
4967 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004968 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004969 }
4970 argvlist[*argc] = NULL;
4971 return argvlist;
4972fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004973 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004974 free_string_array(argvlist, *argc);
4975 return NULL;
4976}
Steve Dowercc16be82016-09-08 10:35:16 -07004977
Ross Lagerwall7807c352011-03-17 20:20:30 +02004978#endif
4979
Larry Hastings2f936352014-08-05 14:04:04 +10004980
Ross Lagerwall7807c352011-03-17 20:20:30 +02004981#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004982/*[clinic input]
4983os.execv
4984
Steve Dowercc16be82016-09-08 10:35:16 -07004985 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004986 Path of executable file.
4987 argv: object
4988 Tuple or list of strings.
4989 /
4990
4991Execute an executable path with arguments, replacing current process.
4992[clinic start generated code]*/
4993
Larry Hastings2f936352014-08-05 14:04:04 +10004994static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004995os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4996/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004997{
Steve Dowercc16be82016-09-08 10:35:16 -07004998 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004999 Py_ssize_t argc;
5000
5001 /* execv has two arguments: (path, argv), where
5002 argv is a list or tuple of strings. */
5003
Ross Lagerwall7807c352011-03-17 20:20:30 +02005004 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5005 PyErr_SetString(PyExc_TypeError,
5006 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005007 return NULL;
5008 }
5009 argc = PySequence_Size(argv);
5010 if (argc < 1) {
5011 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005012 return NULL;
5013 }
5014
5015 argvlist = parse_arglist(argv, &argc);
5016 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005017 return NULL;
5018 }
Steve Dowerbce26262016-11-19 19:17:26 -08005019 if (!argvlist[0][0]) {
5020 PyErr_SetString(PyExc_ValueError,
5021 "execv() arg 2 first element cannot be empty");
5022 free_string_array(argvlist, argc);
5023 return NULL;
5024 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005025
Steve Dowerbce26262016-11-19 19:17:26 -08005026 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005027#ifdef HAVE_WEXECV
5028 _wexecv(path->wide, argvlist);
5029#else
5030 execv(path->narrow, argvlist);
5031#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005032 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005033
5034 /* If we get here it's definitely an error */
5035
5036 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005037 return posix_error();
5038}
5039
Larry Hastings2f936352014-08-05 14:04:04 +10005040
5041/*[clinic input]
5042os.execve
5043
5044 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5045 Path of executable file.
5046 argv: object
5047 Tuple or list of strings.
5048 env: object
5049 Dictionary of strings mapping to strings.
5050
5051Execute an executable path with arguments, replacing current process.
5052[clinic start generated code]*/
5053
Larry Hastings2f936352014-08-05 14:04:04 +10005054static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005055os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5056/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005057{
Steve Dowercc16be82016-09-08 10:35:16 -07005058 EXECV_CHAR **argvlist = NULL;
5059 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005060 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005061
Victor Stinner8c62be82010-05-06 00:08:46 +00005062 /* execve has three arguments: (path, argv, env), where
5063 argv is a list or tuple of strings and env is a dictionary
5064 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005065
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005068 "execve: argv must be a tuple or list");
5069 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005071 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005072 if (argc < 1) {
5073 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5074 return NULL;
5075 }
5076
Victor Stinner8c62be82010-05-06 00:08:46 +00005077 if (!PyMapping_Check(env)) {
5078 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005079 "execve: environment must be a mapping object");
5080 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005081 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005082
Ross Lagerwall7807c352011-03-17 20:20:30 +02005083 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005084 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005085 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005086 }
Steve Dowerbce26262016-11-19 19:17:26 -08005087 if (!argvlist[0][0]) {
5088 PyErr_SetString(PyExc_ValueError,
5089 "execve: argv first element cannot be empty");
5090 goto fail;
5091 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005092
Victor Stinner8c62be82010-05-06 00:08:46 +00005093 envlist = parse_envlist(env, &envc);
5094 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005095 goto fail;
5096
Steve Dowerbce26262016-11-19 19:17:26 -08005097 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005098#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005099 if (path->fd > -1)
5100 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005101 else
5102#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005103#ifdef HAVE_WEXECV
5104 _wexecve(path->wide, argvlist, envlist);
5105#else
Larry Hastings2f936352014-08-05 14:04:04 +10005106 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005107#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005108 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005109
5110 /* If we get here it's definitely an error */
5111
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07005112 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005113
Steve Dowercc16be82016-09-08 10:35:16 -07005114 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005115 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005116 if (argvlist)
5117 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005118 return NULL;
5119}
Steve Dowercc16be82016-09-08 10:35:16 -07005120
Larry Hastings9cf065c2012-06-22 16:30:09 -07005121#endif /* HAVE_EXECV */
5122
Steve Dowercc16be82016-09-08 10:35:16 -07005123#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005124/*[clinic input]
5125os.spawnv
5126
5127 mode: int
5128 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005129 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005130 Path of executable file.
5131 argv: object
5132 Tuple or list of strings.
5133 /
5134
5135Execute the program specified by path in a new process.
5136[clinic start generated code]*/
5137
Larry Hastings2f936352014-08-05 14:04:04 +10005138static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005139os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5140/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005141{
Steve Dowercc16be82016-09-08 10:35:16 -07005142 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005143 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005145 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005147
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 /* spawnv has three arguments: (mode, path, argv), where
5149 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005150
Victor Stinner8c62be82010-05-06 00:08:46 +00005151 if (PyList_Check(argv)) {
5152 argc = PyList_Size(argv);
5153 getitem = PyList_GetItem;
5154 }
5155 else if (PyTuple_Check(argv)) {
5156 argc = PyTuple_Size(argv);
5157 getitem = PyTuple_GetItem;
5158 }
5159 else {
5160 PyErr_SetString(PyExc_TypeError,
5161 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 return NULL;
5163 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005164 if (argc == 0) {
5165 PyErr_SetString(PyExc_ValueError,
5166 "spawnv() arg 2 cannot be empty");
5167 return NULL;
5168 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005169
Steve Dowercc16be82016-09-08 10:35:16 -07005170 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005171 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 return PyErr_NoMemory();
5173 }
5174 for (i = 0; i < argc; i++) {
5175 if (!fsconvert_strdup((*getitem)(argv, i),
5176 &argvlist[i])) {
5177 free_string_array(argvlist, i);
5178 PyErr_SetString(
5179 PyExc_TypeError,
5180 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005181 return NULL;
5182 }
Steve Dower93ff8722016-11-19 19:03:54 -08005183 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005184 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005185 PyErr_SetString(
5186 PyExc_ValueError,
5187 "spawnv() arg 2 first element cannot be empty");
5188 return NULL;
5189 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 }
5191 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005192
Victor Stinner8c62be82010-05-06 00:08:46 +00005193 if (mode == _OLD_P_OVERLAY)
5194 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005195
Victor Stinner8c62be82010-05-06 00:08:46 +00005196 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005197 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005198#ifdef HAVE_WSPAWNV
5199 spawnval = _wspawnv(mode, path->wide, argvlist);
5200#else
5201 spawnval = _spawnv(mode, path->narrow, argvlist);
5202#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005203 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005204 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005205
Victor Stinner8c62be82010-05-06 00:08:46 +00005206 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005207
Victor Stinner8c62be82010-05-06 00:08:46 +00005208 if (spawnval == -1)
5209 return posix_error();
5210 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005211 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005212}
5213
Larry Hastings2f936352014-08-05 14:04:04 +10005214/*[clinic input]
5215os.spawnve
5216
5217 mode: int
5218 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005219 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005220 Path of executable file.
5221 argv: object
5222 Tuple or list of strings.
5223 env: object
5224 Dictionary of strings mapping to strings.
5225 /
5226
5227Execute the program specified by path in a new process.
5228[clinic start generated code]*/
5229
Larry Hastings2f936352014-08-05 14:04:04 +10005230static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005231os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005232 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005233/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005234{
Steve Dowercc16be82016-09-08 10:35:16 -07005235 EXECV_CHAR **argvlist;
5236 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005237 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005238 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005239 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005241 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005242
Victor Stinner8c62be82010-05-06 00:08:46 +00005243 /* spawnve has four arguments: (mode, path, argv, env), where
5244 argv is a list or tuple of strings and env is a dictionary
5245 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005246
Victor Stinner8c62be82010-05-06 00:08:46 +00005247 if (PyList_Check(argv)) {
5248 argc = PyList_Size(argv);
5249 getitem = PyList_GetItem;
5250 }
5251 else if (PyTuple_Check(argv)) {
5252 argc = PyTuple_Size(argv);
5253 getitem = PyTuple_GetItem;
5254 }
5255 else {
5256 PyErr_SetString(PyExc_TypeError,
5257 "spawnve() arg 2 must be a tuple or list");
5258 goto fail_0;
5259 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005260 if (argc == 0) {
5261 PyErr_SetString(PyExc_ValueError,
5262 "spawnve() arg 2 cannot be empty");
5263 goto fail_0;
5264 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 if (!PyMapping_Check(env)) {
5266 PyErr_SetString(PyExc_TypeError,
5267 "spawnve() arg 3 must be a mapping object");
5268 goto fail_0;
5269 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005270
Steve Dowercc16be82016-09-08 10:35:16 -07005271 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 if (argvlist == NULL) {
5273 PyErr_NoMemory();
5274 goto fail_0;
5275 }
5276 for (i = 0; i < argc; i++) {
5277 if (!fsconvert_strdup((*getitem)(argv, i),
5278 &argvlist[i]))
5279 {
5280 lastarg = i;
5281 goto fail_1;
5282 }
Steve Dowerbce26262016-11-19 19:17:26 -08005283 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005284 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005285 PyErr_SetString(
5286 PyExc_ValueError,
5287 "spawnv() arg 2 first element cannot be empty");
5288 goto fail_1;
5289 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005290 }
5291 lastarg = argc;
5292 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005293
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 envlist = parse_envlist(env, &envc);
5295 if (envlist == NULL)
5296 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005297
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 if (mode == _OLD_P_OVERLAY)
5299 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005300
Victor Stinner8c62be82010-05-06 00:08:46 +00005301 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005302 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005303#ifdef HAVE_WSPAWNV
5304 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5305#else
5306 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5307#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005308 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005310
Victor Stinner8c62be82010-05-06 00:08:46 +00005311 if (spawnval == -1)
5312 (void) posix_error();
5313 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005314 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005315
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 while (--envc >= 0)
5317 PyMem_DEL(envlist[envc]);
5318 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005319 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005320 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005321 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005322 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005323}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005324
Guido van Rossuma1065681999-01-25 23:20:23 +00005325#endif /* HAVE_SPAWNV */
5326
5327
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005328#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005329
5330/* Helper function to validate arguments.
5331 Returns 0 on success. non-zero on failure with a TypeError raised.
5332 If obj is non-NULL it must be callable. */
5333static int
5334check_null_or_callable(PyObject *obj, const char* obj_name)
5335{
5336 if (obj && !PyCallable_Check(obj)) {
5337 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5338 obj_name, Py_TYPE(obj)->tp_name);
5339 return -1;
5340 }
5341 return 0;
5342}
5343
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005344/*[clinic input]
5345os.register_at_fork
5346
Gregory P. Smith163468a2017-05-29 10:03:41 -07005347 *
5348 before: object=NULL
5349 A callable to be called in the parent before the fork() syscall.
5350 after_in_child: object=NULL
5351 A callable to be called in the child after fork().
5352 after_in_parent: object=NULL
5353 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005354
Gregory P. Smith163468a2017-05-29 10:03:41 -07005355Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005356
Gregory P. Smith163468a2017-05-29 10:03:41 -07005357'before' callbacks are called in reverse order.
5358'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005359
5360[clinic start generated code]*/
5361
5362static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005363os_register_at_fork_impl(PyObject *module, PyObject *before,
5364 PyObject *after_in_child, PyObject *after_in_parent)
5365/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005366{
5367 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005368
Gregory P. Smith163468a2017-05-29 10:03:41 -07005369 if (!before && !after_in_child && !after_in_parent) {
5370 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5371 return NULL;
5372 }
5373 if (check_null_or_callable(before, "before") ||
5374 check_null_or_callable(after_in_child, "after_in_child") ||
5375 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005376 return NULL;
5377 }
5378 interp = PyThreadState_Get()->interp;
5379
Gregory P. Smith163468a2017-05-29 10:03:41 -07005380 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005381 return NULL;
5382 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005383 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005384 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005385 }
5386 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5387 return NULL;
5388 }
5389 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005390}
5391#endif /* HAVE_FORK */
5392
5393
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005394#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005395/*[clinic input]
5396os.fork1
5397
5398Fork a child process with a single multiplexed (i.e., not bound) thread.
5399
5400Return 0 to child process and PID of child to parent process.
5401[clinic start generated code]*/
5402
Larry Hastings2f936352014-08-05 14:04:04 +10005403static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005404os_fork1_impl(PyObject *module)
5405/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005406{
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005408
5409 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 pid = fork1();
5411 if (pid == 0) {
5412 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005413 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 } else {
5415 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005416 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005417 }
5418 if (pid == -1)
5419 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005420 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005421}
Larry Hastings2f936352014-08-05 14:04:04 +10005422#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005423
5424
Guido van Rossumad0ee831995-03-01 10:34:45 +00005425#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005426/*[clinic input]
5427os.fork
5428
5429Fork a child process.
5430
5431Return 0 to child process and PID of child to parent process.
5432[clinic start generated code]*/
5433
Larry Hastings2f936352014-08-05 14:04:04 +10005434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005435os_fork_impl(PyObject *module)
5436/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005437{
Victor Stinner8c62be82010-05-06 00:08:46 +00005438 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005439
5440 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005441 pid = fork();
5442 if (pid == 0) {
5443 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005444 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005445 } else {
5446 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005447 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005448 }
5449 if (pid == -1)
5450 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005451 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005452}
Larry Hastings2f936352014-08-05 14:04:04 +10005453#endif /* HAVE_FORK */
5454
Guido van Rossum85e3b011991-06-03 12:42:10 +00005455
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005456#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005457#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005458/*[clinic input]
5459os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005460
Larry Hastings2f936352014-08-05 14:04:04 +10005461 policy: int
5462
5463Get the maximum scheduling priority for policy.
5464[clinic start generated code]*/
5465
Larry Hastings2f936352014-08-05 14:04:04 +10005466static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005467os_sched_get_priority_max_impl(PyObject *module, int policy)
5468/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005469{
5470 int max;
5471
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005472 max = sched_get_priority_max(policy);
5473 if (max < 0)
5474 return posix_error();
5475 return PyLong_FromLong(max);
5476}
5477
Larry Hastings2f936352014-08-05 14:04:04 +10005478
5479/*[clinic input]
5480os.sched_get_priority_min
5481
5482 policy: int
5483
5484Get the minimum scheduling priority for policy.
5485[clinic start generated code]*/
5486
Larry Hastings2f936352014-08-05 14:04:04 +10005487static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005488os_sched_get_priority_min_impl(PyObject *module, int policy)
5489/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005490{
5491 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005492 if (min < 0)
5493 return posix_error();
5494 return PyLong_FromLong(min);
5495}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005496#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5497
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005498
Larry Hastings2f936352014-08-05 14:04:04 +10005499#ifdef HAVE_SCHED_SETSCHEDULER
5500/*[clinic input]
5501os.sched_getscheduler
5502 pid: pid_t
5503 /
5504
5505Get the scheduling policy for the process identifiedy by pid.
5506
5507Passing 0 for pid returns the scheduling policy for the calling process.
5508[clinic start generated code]*/
5509
Larry Hastings2f936352014-08-05 14:04:04 +10005510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005511os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5512/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005513{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005514 int policy;
5515
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005516 policy = sched_getscheduler(pid);
5517 if (policy < 0)
5518 return posix_error();
5519 return PyLong_FromLong(policy);
5520}
Larry Hastings2f936352014-08-05 14:04:04 +10005521#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005522
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005523
5524#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005525/*[clinic input]
5526class os.sched_param "PyObject *" "&SchedParamType"
5527
5528@classmethod
5529os.sched_param.__new__
5530
5531 sched_priority: object
5532 A scheduling parameter.
5533
5534Current has only one field: sched_priority");
5535[clinic start generated code]*/
5536
Larry Hastings2f936352014-08-05 14:04:04 +10005537static PyObject *
5538os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005539/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005540{
5541 PyObject *res;
5542
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005543 res = PyStructSequence_New(type);
5544 if (!res)
5545 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005546 Py_INCREF(sched_priority);
5547 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005548 return res;
5549}
5550
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005551
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005552PyDoc_VAR(os_sched_param__doc__);
5553
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005554static PyStructSequence_Field sched_param_fields[] = {
5555 {"sched_priority", "the scheduling priority"},
5556 {0}
5557};
5558
5559static PyStructSequence_Desc sched_param_desc = {
5560 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005561 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005562 sched_param_fields,
5563 1
5564};
5565
5566static int
5567convert_sched_param(PyObject *param, struct sched_param *res)
5568{
5569 long priority;
5570
5571 if (Py_TYPE(param) != &SchedParamType) {
5572 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5573 return 0;
5574 }
5575 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5576 if (priority == -1 && PyErr_Occurred())
5577 return 0;
5578 if (priority > INT_MAX || priority < INT_MIN) {
5579 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5580 return 0;
5581 }
5582 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5583 return 1;
5584}
Larry Hastings2f936352014-08-05 14:04:04 +10005585#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005586
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005587
5588#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005589/*[clinic input]
5590os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005591
Larry Hastings2f936352014-08-05 14:04:04 +10005592 pid: pid_t
5593 policy: int
5594 param: sched_param
5595 /
5596
5597Set the scheduling policy for the process identified by pid.
5598
5599If pid is 0, the calling process is changed.
5600param is an instance of sched_param.
5601[clinic start generated code]*/
5602
Larry Hastings2f936352014-08-05 14:04:04 +10005603static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005604os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005605 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005606/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005607{
Jesus Cea9c822272011-09-10 01:40:52 +02005608 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005609 ** sched_setscheduler() returns 0 in Linux, but the previous
5610 ** scheduling policy under Solaris/Illumos, and others.
5611 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005612 */
Larry Hastings2f936352014-08-05 14:04:04 +10005613 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005614 return posix_error();
5615 Py_RETURN_NONE;
5616}
Larry Hastings2f936352014-08-05 14:04:04 +10005617#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005618
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005619
5620#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005621/*[clinic input]
5622os.sched_getparam
5623 pid: pid_t
5624 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005625
Larry Hastings2f936352014-08-05 14:04:04 +10005626Returns scheduling parameters for the process identified by pid.
5627
5628If pid is 0, returns parameters for the calling process.
5629Return value is an instance of sched_param.
5630[clinic start generated code]*/
5631
Larry Hastings2f936352014-08-05 14:04:04 +10005632static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005633os_sched_getparam_impl(PyObject *module, pid_t pid)
5634/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005635{
5636 struct sched_param param;
5637 PyObject *result;
5638 PyObject *priority;
5639
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005640 if (sched_getparam(pid, &param))
5641 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005642 result = PyStructSequence_New(&SchedParamType);
5643 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005644 return NULL;
5645 priority = PyLong_FromLong(param.sched_priority);
5646 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005647 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005648 return NULL;
5649 }
Larry Hastings2f936352014-08-05 14:04:04 +10005650 PyStructSequence_SET_ITEM(result, 0, priority);
5651 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005652}
5653
Larry Hastings2f936352014-08-05 14:04:04 +10005654
5655/*[clinic input]
5656os.sched_setparam
5657 pid: pid_t
5658 param: sched_param
5659 /
5660
5661Set scheduling parameters for the process identified by pid.
5662
5663If pid is 0, sets parameters for the calling process.
5664param should be an instance of sched_param.
5665[clinic start generated code]*/
5666
Larry Hastings2f936352014-08-05 14:04:04 +10005667static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005668os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005669 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005670/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005671{
5672 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005673 return posix_error();
5674 Py_RETURN_NONE;
5675}
Larry Hastings2f936352014-08-05 14:04:04 +10005676#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005677
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005678
5679#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005680/*[clinic input]
5681os.sched_rr_get_interval -> double
5682 pid: pid_t
5683 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005684
Larry Hastings2f936352014-08-05 14:04:04 +10005685Return the round-robin quantum for the process identified by pid, in seconds.
5686
5687Value returned is a float.
5688[clinic start generated code]*/
5689
Larry Hastings2f936352014-08-05 14:04:04 +10005690static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005691os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5692/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005693{
5694 struct timespec interval;
5695 if (sched_rr_get_interval(pid, &interval)) {
5696 posix_error();
5697 return -1.0;
5698 }
5699 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5700}
5701#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005702
Larry Hastings2f936352014-08-05 14:04:04 +10005703
5704/*[clinic input]
5705os.sched_yield
5706
5707Voluntarily relinquish the CPU.
5708[clinic start generated code]*/
5709
Larry Hastings2f936352014-08-05 14:04:04 +10005710static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005711os_sched_yield_impl(PyObject *module)
5712/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005713{
5714 if (sched_yield())
5715 return posix_error();
5716 Py_RETURN_NONE;
5717}
5718
Benjamin Peterson2740af82011-08-02 17:41:34 -05005719#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005720/* The minimum number of CPUs allocated in a cpu_set_t */
5721static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005722
Larry Hastings2f936352014-08-05 14:04:04 +10005723/*[clinic input]
5724os.sched_setaffinity
5725 pid: pid_t
5726 mask : object
5727 /
5728
5729Set the CPU affinity of the process identified by pid to mask.
5730
5731mask should be an iterable of integers identifying CPUs.
5732[clinic start generated code]*/
5733
Larry Hastings2f936352014-08-05 14:04:04 +10005734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005735os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5736/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005737{
Antoine Pitrou84869872012-08-04 16:16:35 +02005738 int ncpus;
5739 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005740 cpu_set_t *cpu_set = NULL;
5741 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005742
Larry Hastings2f936352014-08-05 14:04:04 +10005743 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005744 if (iterator == NULL)
5745 return NULL;
5746
5747 ncpus = NCPUS_START;
5748 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005749 cpu_set = CPU_ALLOC(ncpus);
5750 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005751 PyErr_NoMemory();
5752 goto error;
5753 }
Larry Hastings2f936352014-08-05 14:04:04 +10005754 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005755
5756 while ((item = PyIter_Next(iterator))) {
5757 long cpu;
5758 if (!PyLong_Check(item)) {
5759 PyErr_Format(PyExc_TypeError,
5760 "expected an iterator of ints, "
5761 "but iterator yielded %R",
5762 Py_TYPE(item));
5763 Py_DECREF(item);
5764 goto error;
5765 }
5766 cpu = PyLong_AsLong(item);
5767 Py_DECREF(item);
5768 if (cpu < 0) {
5769 if (!PyErr_Occurred())
5770 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5771 goto error;
5772 }
5773 if (cpu > INT_MAX - 1) {
5774 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5775 goto error;
5776 }
5777 if (cpu >= ncpus) {
5778 /* Grow CPU mask to fit the CPU number */
5779 int newncpus = ncpus;
5780 cpu_set_t *newmask;
5781 size_t newsetsize;
5782 while (newncpus <= cpu) {
5783 if (newncpus > INT_MAX / 2)
5784 newncpus = cpu + 1;
5785 else
5786 newncpus = newncpus * 2;
5787 }
5788 newmask = CPU_ALLOC(newncpus);
5789 if (newmask == NULL) {
5790 PyErr_NoMemory();
5791 goto error;
5792 }
5793 newsetsize = CPU_ALLOC_SIZE(newncpus);
5794 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005795 memcpy(newmask, cpu_set, setsize);
5796 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005797 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005798 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005799 ncpus = newncpus;
5800 }
Larry Hastings2f936352014-08-05 14:04:04 +10005801 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005802 }
5803 Py_CLEAR(iterator);
5804
Larry Hastings2f936352014-08-05 14:04:04 +10005805 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005806 posix_error();
5807 goto error;
5808 }
Larry Hastings2f936352014-08-05 14:04:04 +10005809 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005810 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005811
5812error:
Larry Hastings2f936352014-08-05 14:04:04 +10005813 if (cpu_set)
5814 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005815 Py_XDECREF(iterator);
5816 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005817}
5818
Larry Hastings2f936352014-08-05 14:04:04 +10005819
5820/*[clinic input]
5821os.sched_getaffinity
5822 pid: pid_t
5823 /
5824
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005825Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005826
5827The affinity is returned as a set of CPU identifiers.
5828[clinic start generated code]*/
5829
Larry Hastings2f936352014-08-05 14:04:04 +10005830static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005831os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005832/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005833{
Antoine Pitrou84869872012-08-04 16:16:35 +02005834 int cpu, ncpus, count;
5835 size_t setsize;
5836 cpu_set_t *mask = NULL;
5837 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005838
Antoine Pitrou84869872012-08-04 16:16:35 +02005839 ncpus = NCPUS_START;
5840 while (1) {
5841 setsize = CPU_ALLOC_SIZE(ncpus);
5842 mask = CPU_ALLOC(ncpus);
5843 if (mask == NULL)
5844 return PyErr_NoMemory();
5845 if (sched_getaffinity(pid, setsize, mask) == 0)
5846 break;
5847 CPU_FREE(mask);
5848 if (errno != EINVAL)
5849 return posix_error();
5850 if (ncpus > INT_MAX / 2) {
5851 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5852 "a large enough CPU set");
5853 return NULL;
5854 }
5855 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005856 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005857
5858 res = PySet_New(NULL);
5859 if (res == NULL)
5860 goto error;
5861 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5862 if (CPU_ISSET_S(cpu, setsize, mask)) {
5863 PyObject *cpu_num = PyLong_FromLong(cpu);
5864 --count;
5865 if (cpu_num == NULL)
5866 goto error;
5867 if (PySet_Add(res, cpu_num)) {
5868 Py_DECREF(cpu_num);
5869 goto error;
5870 }
5871 Py_DECREF(cpu_num);
5872 }
5873 }
5874 CPU_FREE(mask);
5875 return res;
5876
5877error:
5878 if (mask)
5879 CPU_FREE(mask);
5880 Py_XDECREF(res);
5881 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005882}
5883
Benjamin Peterson2740af82011-08-02 17:41:34 -05005884#endif /* HAVE_SCHED_SETAFFINITY */
5885
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005886#endif /* HAVE_SCHED_H */
5887
Larry Hastings2f936352014-08-05 14:04:04 +10005888
Neal Norwitzb59798b2003-03-21 01:43:31 +00005889/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005890/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5891#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005892#define DEV_PTY_FILE "/dev/ptc"
5893#define HAVE_DEV_PTMX
5894#else
5895#define DEV_PTY_FILE "/dev/ptmx"
5896#endif
5897
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005898#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005899#ifdef HAVE_PTY_H
5900#include <pty.h>
5901#else
5902#ifdef HAVE_LIBUTIL_H
5903#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005904#else
5905#ifdef HAVE_UTIL_H
5906#include <util.h>
5907#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005908#endif /* HAVE_LIBUTIL_H */
5909#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005910#ifdef HAVE_STROPTS_H
5911#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005912#endif
Miss Islington (bot)f0616ce2018-02-14 13:06:46 -08005913#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005914
Larry Hastings2f936352014-08-05 14:04:04 +10005915
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005916#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005917/*[clinic input]
5918os.openpty
5919
5920Open a pseudo-terminal.
5921
5922Return a tuple of (master_fd, slave_fd) containing open file descriptors
5923for both the master and slave ends.
5924[clinic start generated code]*/
5925
Larry Hastings2f936352014-08-05 14:04:04 +10005926static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005927os_openpty_impl(PyObject *module)
5928/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005929{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005930 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005931#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005933#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005934#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005936#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005937 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005938#endif
5939#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005940
Thomas Wouters70c21a12000-07-14 14:28:33 +00005941#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005943 goto posix_error;
5944
5945 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5946 goto error;
5947 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5948 goto error;
5949
Neal Norwitzb59798b2003-03-21 01:43:31 +00005950#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5952 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005953 goto posix_error;
5954 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5955 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005956
Victor Stinnerdaf45552013-08-28 00:53:59 +02005957 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005958 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005959 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005960
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005961#else
Victor Stinner000de532013-11-25 23:19:58 +01005962 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005964 goto posix_error;
5965
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005967
Victor Stinner8c62be82010-05-06 00:08:46 +00005968 /* change permission of slave */
5969 if (grantpt(master_fd) < 0) {
5970 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005971 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005972 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005973
Victor Stinner8c62be82010-05-06 00:08:46 +00005974 /* unlock slave */
5975 if (unlockpt(master_fd) < 0) {
5976 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005977 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005978 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005979
Victor Stinner8c62be82010-05-06 00:08:46 +00005980 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005981
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 slave_name = ptsname(master_fd); /* get name of slave */
5983 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005984 goto posix_error;
5985
5986 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005987 if (slave_fd == -1)
5988 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005989
5990 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5991 goto posix_error;
5992
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005993#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005994 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5995 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005996#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005998#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005999#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006000#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006001
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006003
Victor Stinnerdaf45552013-08-28 00:53:59 +02006004posix_error:
6005 posix_error();
6006error:
6007 if (master_fd != -1)
6008 close(master_fd);
6009 if (slave_fd != -1)
6010 close(slave_fd);
6011 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006012}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006013#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006014
Larry Hastings2f936352014-08-05 14:04:04 +10006015
Fred Drake8cef4cf2000-06-28 16:40:38 +00006016#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006017/*[clinic input]
6018os.forkpty
6019
6020Fork a new process with a new pseudo-terminal as controlling tty.
6021
6022Returns a tuple of (pid, master_fd).
6023Like fork(), return pid of 0 to the child process,
6024and pid of child to the parent process.
6025To both, return fd of newly opened pseudo-terminal.
6026[clinic start generated code]*/
6027
Larry Hastings2f936352014-08-05 14:04:04 +10006028static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006029os_forkpty_impl(PyObject *module)
6030/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006031{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006032 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006034
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006035 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 pid = forkpty(&master_fd, NULL, NULL, NULL);
6037 if (pid == 0) {
6038 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006039 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006040 } else {
6041 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006042 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 }
6044 if (pid == -1)
6045 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006046 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006047}
Larry Hastings2f936352014-08-05 14:04:04 +10006048#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006049
Ross Lagerwall7807c352011-03-17 20:20:30 +02006050
Guido van Rossumad0ee831995-03-01 10:34:45 +00006051#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006052/*[clinic input]
6053os.getegid
6054
6055Return the current process's effective group id.
6056[clinic start generated code]*/
6057
Larry Hastings2f936352014-08-05 14:04:04 +10006058static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006059os_getegid_impl(PyObject *module)
6060/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006061{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006062 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006063}
Larry Hastings2f936352014-08-05 14:04:04 +10006064#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006066
Guido van Rossumad0ee831995-03-01 10:34:45 +00006067#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006068/*[clinic input]
6069os.geteuid
6070
6071Return the current process's effective user id.
6072[clinic start generated code]*/
6073
Larry Hastings2f936352014-08-05 14:04:04 +10006074static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006075os_geteuid_impl(PyObject *module)
6076/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006077{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006078 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006079}
Larry Hastings2f936352014-08-05 14:04:04 +10006080#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006082
Guido van Rossumad0ee831995-03-01 10:34:45 +00006083#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006084/*[clinic input]
6085os.getgid
6086
6087Return the current process's group id.
6088[clinic start generated code]*/
6089
Larry Hastings2f936352014-08-05 14:04:04 +10006090static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006091os_getgid_impl(PyObject *module)
6092/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006093{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006094 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006095}
Larry Hastings2f936352014-08-05 14:04:04 +10006096#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006098
Berker Peksag39404992016-09-15 20:45:16 +03006099#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006100/*[clinic input]
6101os.getpid
6102
6103Return the current process id.
6104[clinic start generated code]*/
6105
Larry Hastings2f936352014-08-05 14:04:04 +10006106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006107os_getpid_impl(PyObject *module)
6108/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006109{
Victor Stinner8c62be82010-05-06 00:08:46 +00006110 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006111}
Berker Peksag39404992016-09-15 20:45:16 +03006112#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006113
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006114#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006115
6116/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006117PyDoc_STRVAR(posix_getgrouplist__doc__,
6118"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6119Returns a list of groups to which a user belongs.\n\n\
6120 user: username to lookup\n\
6121 group: base group id of the user");
6122
6123static PyObject *
6124posix_getgrouplist(PyObject *self, PyObject *args)
6125{
6126#ifdef NGROUPS_MAX
6127#define MAX_GROUPS NGROUPS_MAX
6128#else
6129 /* defined to be 16 on Solaris7, so this should be a small number */
6130#define MAX_GROUPS 64
6131#endif
6132
6133 const char *user;
6134 int i, ngroups;
6135 PyObject *list;
6136#ifdef __APPLE__
6137 int *groups, basegid;
6138#else
6139 gid_t *groups, basegid;
6140#endif
6141 ngroups = MAX_GROUPS;
6142
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006143#ifdef __APPLE__
6144 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006145 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006146#else
6147 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6148 _Py_Gid_Converter, &basegid))
6149 return NULL;
6150#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006151
6152#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006153 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006154#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006155 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006156#endif
6157 if (groups == NULL)
6158 return PyErr_NoMemory();
6159
6160 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6161 PyMem_Del(groups);
6162 return posix_error();
6163 }
6164
6165 list = PyList_New(ngroups);
6166 if (list == NULL) {
6167 PyMem_Del(groups);
6168 return NULL;
6169 }
6170
6171 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006172#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006173 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006174#else
6175 PyObject *o = _PyLong_FromGid(groups[i]);
6176#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006177 if (o == NULL) {
6178 Py_DECREF(list);
6179 PyMem_Del(groups);
6180 return NULL;
6181 }
6182 PyList_SET_ITEM(list, i, o);
6183 }
6184
6185 PyMem_Del(groups);
6186
6187 return list;
6188}
Larry Hastings2f936352014-08-05 14:04:04 +10006189#endif /* HAVE_GETGROUPLIST */
6190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006191
Fred Drakec9680921999-12-13 16:37:25 +00006192#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006193/*[clinic input]
6194os.getgroups
6195
6196Return list of supplemental group IDs for the process.
6197[clinic start generated code]*/
6198
Larry Hastings2f936352014-08-05 14:04:04 +10006199static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006200os_getgroups_impl(PyObject *module)
6201/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006202{
6203 PyObject *result = NULL;
6204
Fred Drakec9680921999-12-13 16:37:25 +00006205#ifdef NGROUPS_MAX
6206#define MAX_GROUPS NGROUPS_MAX
6207#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006208 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006209#define MAX_GROUPS 64
6210#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006211 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006212
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006213 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006214 * This is a helper variable to store the intermediate result when
6215 * that happens.
6216 *
6217 * To keep the code readable the OSX behaviour is unconditional,
6218 * according to the POSIX spec this should be safe on all unix-y
6219 * systems.
6220 */
6221 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006223
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006224#ifdef __APPLE__
6225 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6226 * there are more groups than can fit in grouplist. Therefore, on OS X
6227 * always first call getgroups with length 0 to get the actual number
6228 * of groups.
6229 */
6230 n = getgroups(0, NULL);
6231 if (n < 0) {
6232 return posix_error();
6233 } else if (n <= MAX_GROUPS) {
6234 /* groups will fit in existing array */
6235 alt_grouplist = grouplist;
6236 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006237 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006238 if (alt_grouplist == NULL) {
6239 errno = EINVAL;
6240 return posix_error();
6241 }
6242 }
6243
6244 n = getgroups(n, alt_grouplist);
6245 if (n == -1) {
6246 if (alt_grouplist != grouplist) {
6247 PyMem_Free(alt_grouplist);
6248 }
6249 return posix_error();
6250 }
6251#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006253 if (n < 0) {
6254 if (errno == EINVAL) {
6255 n = getgroups(0, NULL);
6256 if (n == -1) {
6257 return posix_error();
6258 }
6259 if (n == 0) {
6260 /* Avoid malloc(0) */
6261 alt_grouplist = grouplist;
6262 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006263 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006264 if (alt_grouplist == NULL) {
6265 errno = EINVAL;
6266 return posix_error();
6267 }
6268 n = getgroups(n, alt_grouplist);
6269 if (n == -1) {
6270 PyMem_Free(alt_grouplist);
6271 return posix_error();
6272 }
6273 }
6274 } else {
6275 return posix_error();
6276 }
6277 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006278#endif
6279
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006280 result = PyList_New(n);
6281 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006282 int i;
6283 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006284 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006285 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006286 Py_DECREF(result);
6287 result = NULL;
6288 break;
Fred Drakec9680921999-12-13 16:37:25 +00006289 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006291 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006292 }
6293
6294 if (alt_grouplist != grouplist) {
6295 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006297
Fred Drakec9680921999-12-13 16:37:25 +00006298 return result;
6299}
Larry Hastings2f936352014-08-05 14:04:04 +10006300#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006301
Antoine Pitroub7572f02009-12-02 20:46:48 +00006302#ifdef HAVE_INITGROUPS
6303PyDoc_STRVAR(posix_initgroups__doc__,
6304"initgroups(username, gid) -> None\n\n\
6305Call the system initgroups() to initialize the group access list with all of\n\
6306the groups of which the specified username is a member, plus the specified\n\
6307group id.");
6308
Larry Hastings2f936352014-08-05 14:04:04 +10006309/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006310static PyObject *
6311posix_initgroups(PyObject *self, PyObject *args)
6312{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006313 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006314 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006315 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006316#ifdef __APPLE__
6317 int gid;
6318#else
6319 gid_t gid;
6320#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006321
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006322#ifdef __APPLE__
6323 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6324 PyUnicode_FSConverter, &oname,
6325 &gid))
6326#else
6327 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6328 PyUnicode_FSConverter, &oname,
6329 _Py_Gid_Converter, &gid))
6330#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006331 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006332 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006333
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006334 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006335 Py_DECREF(oname);
6336 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006337 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006338
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006339 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006340}
Larry Hastings2f936352014-08-05 14:04:04 +10006341#endif /* HAVE_INITGROUPS */
6342
Antoine Pitroub7572f02009-12-02 20:46:48 +00006343
Martin v. Löwis606edc12002-06-13 21:09:11 +00006344#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006345/*[clinic input]
6346os.getpgid
6347
6348 pid: pid_t
6349
6350Call the system call getpgid(), and return the result.
6351[clinic start generated code]*/
6352
Larry Hastings2f936352014-08-05 14:04:04 +10006353static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006354os_getpgid_impl(PyObject *module, pid_t pid)
6355/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006356{
6357 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 if (pgid < 0)
6359 return posix_error();
6360 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006361}
6362#endif /* HAVE_GETPGID */
6363
6364
Guido van Rossumb6775db1994-08-01 11:34:53 +00006365#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006366/*[clinic input]
6367os.getpgrp
6368
6369Return the current process group id.
6370[clinic start generated code]*/
6371
Larry Hastings2f936352014-08-05 14:04:04 +10006372static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006373os_getpgrp_impl(PyObject *module)
6374/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006375{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006376#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006377 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006378#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006379 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006380#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006381}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006382#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006383
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006384
Guido van Rossumb6775db1994-08-01 11:34:53 +00006385#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006386/*[clinic input]
6387os.setpgrp
6388
6389Make the current process the leader of its process group.
6390[clinic start generated code]*/
6391
Larry Hastings2f936352014-08-05 14:04:04 +10006392static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006393os_setpgrp_impl(PyObject *module)
6394/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006395{
Guido van Rossum64933891994-10-20 21:56:42 +00006396#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006398#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006400#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006401 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006402 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006403}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006404#endif /* HAVE_SETPGRP */
6405
Guido van Rossumad0ee831995-03-01 10:34:45 +00006406#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006407
6408#ifdef MS_WINDOWS
6409#include <tlhelp32.h>
6410
6411static PyObject*
6412win32_getppid()
6413{
6414 HANDLE snapshot;
6415 pid_t mypid;
6416 PyObject* result = NULL;
6417 BOOL have_record;
6418 PROCESSENTRY32 pe;
6419
6420 mypid = getpid(); /* This function never fails */
6421
6422 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6423 if (snapshot == INVALID_HANDLE_VALUE)
6424 return PyErr_SetFromWindowsErr(GetLastError());
6425
6426 pe.dwSize = sizeof(pe);
6427 have_record = Process32First(snapshot, &pe);
6428 while (have_record) {
6429 if (mypid == (pid_t)pe.th32ProcessID) {
6430 /* We could cache the ulong value in a static variable. */
6431 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6432 break;
6433 }
6434
6435 have_record = Process32Next(snapshot, &pe);
6436 }
6437
6438 /* If our loop exits and our pid was not found (result will be NULL)
6439 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6440 * error anyway, so let's raise it. */
6441 if (!result)
6442 result = PyErr_SetFromWindowsErr(GetLastError());
6443
6444 CloseHandle(snapshot);
6445
6446 return result;
6447}
6448#endif /*MS_WINDOWS*/
6449
Larry Hastings2f936352014-08-05 14:04:04 +10006450
6451/*[clinic input]
6452os.getppid
6453
6454Return the parent's process id.
6455
6456If the parent process has already exited, Windows machines will still
6457return its id; others systems will return the id of the 'init' process (1).
6458[clinic start generated code]*/
6459
Larry Hastings2f936352014-08-05 14:04:04 +10006460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006461os_getppid_impl(PyObject *module)
6462/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006463{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006464#ifdef MS_WINDOWS
6465 return win32_getppid();
6466#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006468#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006469}
6470#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006472
Fred Drake12c6e2d1999-12-14 21:25:03 +00006473#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006474/*[clinic input]
6475os.getlogin
6476
6477Return the actual login name.
6478[clinic start generated code]*/
6479
Larry Hastings2f936352014-08-05 14:04:04 +10006480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006481os_getlogin_impl(PyObject *module)
6482/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006483{
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006485#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006486 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006487 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006488
6489 if (GetUserNameW(user_name, &num_chars)) {
6490 /* num_chars is the number of unicode chars plus null terminator */
6491 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006492 }
6493 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006494 result = PyErr_SetFromWindowsErr(GetLastError());
6495#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006496 char *name;
6497 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006498
Victor Stinner8c62be82010-05-06 00:08:46 +00006499 errno = 0;
6500 name = getlogin();
6501 if (name == NULL) {
6502 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006503 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006504 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006505 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 }
6507 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006508 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006510#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006511 return result;
6512}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006513#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006514
Larry Hastings2f936352014-08-05 14:04:04 +10006515
Guido van Rossumad0ee831995-03-01 10:34:45 +00006516#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006517/*[clinic input]
6518os.getuid
6519
6520Return the current process's user id.
6521[clinic start generated code]*/
6522
Larry Hastings2f936352014-08-05 14:04:04 +10006523static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006524os_getuid_impl(PyObject *module)
6525/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006526{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006527 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006528}
Larry Hastings2f936352014-08-05 14:04:04 +10006529#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006530
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006531
Brian Curtineb24d742010-04-12 17:16:38 +00006532#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006533#define HAVE_KILL
6534#endif /* MS_WINDOWS */
6535
6536#ifdef HAVE_KILL
6537/*[clinic input]
6538os.kill
6539
6540 pid: pid_t
6541 signal: Py_ssize_t
6542 /
6543
6544Kill a process with a signal.
6545[clinic start generated code]*/
6546
Larry Hastings2f936352014-08-05 14:04:04 +10006547static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006548os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6549/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006550#ifndef MS_WINDOWS
6551{
6552 if (kill(pid, (int)signal) == -1)
6553 return posix_error();
6554 Py_RETURN_NONE;
6555}
6556#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006557{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006558 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006559 DWORD sig = (DWORD)signal;
6560 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006562
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 /* Console processes which share a common console can be sent CTRL+C or
6564 CTRL+BREAK events, provided they handle said events. */
6565 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006566 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 err = GetLastError();
6568 PyErr_SetFromWindowsErr(err);
6569 }
6570 else
6571 Py_RETURN_NONE;
6572 }
Brian Curtineb24d742010-04-12 17:16:38 +00006573
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6575 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006576 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006577 if (handle == NULL) {
6578 err = GetLastError();
6579 return PyErr_SetFromWindowsErr(err);
6580 }
Brian Curtineb24d742010-04-12 17:16:38 +00006581
Victor Stinner8c62be82010-05-06 00:08:46 +00006582 if (TerminateProcess(handle, sig) == 0) {
6583 err = GetLastError();
6584 result = PyErr_SetFromWindowsErr(err);
6585 } else {
6586 Py_INCREF(Py_None);
6587 result = Py_None;
6588 }
Brian Curtineb24d742010-04-12 17:16:38 +00006589
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 CloseHandle(handle);
6591 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006592}
Larry Hastings2f936352014-08-05 14:04:04 +10006593#endif /* !MS_WINDOWS */
6594#endif /* HAVE_KILL */
6595
6596
6597#ifdef HAVE_KILLPG
6598/*[clinic input]
6599os.killpg
6600
6601 pgid: pid_t
6602 signal: int
6603 /
6604
6605Kill a process group with a signal.
6606[clinic start generated code]*/
6607
Larry Hastings2f936352014-08-05 14:04:04 +10006608static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006609os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6610/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006611{
6612 /* XXX some man pages make the `pgid` parameter an int, others
6613 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6614 take the same type. Moreover, pid_t is always at least as wide as
6615 int (else compilation of this module fails), which is safe. */
6616 if (killpg(pgid, signal) == -1)
6617 return posix_error();
6618 Py_RETURN_NONE;
6619}
6620#endif /* HAVE_KILLPG */
6621
Brian Curtineb24d742010-04-12 17:16:38 +00006622
Guido van Rossumc0125471996-06-28 18:55:32 +00006623#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006624#ifdef HAVE_SYS_LOCK_H
6625#include <sys/lock.h>
6626#endif
6627
Larry Hastings2f936352014-08-05 14:04:04 +10006628/*[clinic input]
6629os.plock
6630 op: int
6631 /
6632
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006633Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006634[clinic start generated code]*/
6635
Larry Hastings2f936352014-08-05 14:04:04 +10006636static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006637os_plock_impl(PyObject *module, int op)
6638/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006639{
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 if (plock(op) == -1)
6641 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006642 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006643}
Larry Hastings2f936352014-08-05 14:04:04 +10006644#endif /* HAVE_PLOCK */
6645
Guido van Rossumc0125471996-06-28 18:55:32 +00006646
Guido van Rossumb6775db1994-08-01 11:34:53 +00006647#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006648/*[clinic input]
6649os.setuid
6650
6651 uid: uid_t
6652 /
6653
6654Set the current process's user id.
6655[clinic start generated code]*/
6656
Larry Hastings2f936352014-08-05 14:04:04 +10006657static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006658os_setuid_impl(PyObject *module, uid_t uid)
6659/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006660{
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 if (setuid(uid) < 0)
6662 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006663 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006664}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006665#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006666
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006667
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006668#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006669/*[clinic input]
6670os.seteuid
6671
6672 euid: uid_t
6673 /
6674
6675Set the current process's effective user id.
6676[clinic start generated code]*/
6677
Larry Hastings2f936352014-08-05 14:04:04 +10006678static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006679os_seteuid_impl(PyObject *module, uid_t euid)
6680/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006681{
6682 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006683 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006684 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006685}
6686#endif /* HAVE_SETEUID */
6687
Larry Hastings2f936352014-08-05 14:04:04 +10006688
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006689#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006690/*[clinic input]
6691os.setegid
6692
6693 egid: gid_t
6694 /
6695
6696Set the current process's effective group id.
6697[clinic start generated code]*/
6698
Larry Hastings2f936352014-08-05 14:04:04 +10006699static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006700os_setegid_impl(PyObject *module, gid_t egid)
6701/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006702{
6703 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006704 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006705 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006706}
6707#endif /* HAVE_SETEGID */
6708
Larry Hastings2f936352014-08-05 14:04:04 +10006709
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006710#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006711/*[clinic input]
6712os.setreuid
6713
6714 ruid: uid_t
6715 euid: uid_t
6716 /
6717
6718Set the current process's real and effective user ids.
6719[clinic start generated code]*/
6720
Larry Hastings2f936352014-08-05 14:04:04 +10006721static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006722os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6723/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006724{
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 if (setreuid(ruid, euid) < 0) {
6726 return posix_error();
6727 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006728 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006730}
6731#endif /* HAVE_SETREUID */
6732
Larry Hastings2f936352014-08-05 14:04:04 +10006733
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006734#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006735/*[clinic input]
6736os.setregid
6737
6738 rgid: gid_t
6739 egid: gid_t
6740 /
6741
6742Set the current process's real and effective group ids.
6743[clinic start generated code]*/
6744
Larry Hastings2f936352014-08-05 14:04:04 +10006745static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006746os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6747/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006748{
6749 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006750 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006751 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006752}
6753#endif /* HAVE_SETREGID */
6754
Larry Hastings2f936352014-08-05 14:04:04 +10006755
Guido van Rossumb6775db1994-08-01 11:34:53 +00006756#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006757/*[clinic input]
6758os.setgid
6759 gid: gid_t
6760 /
6761
6762Set the current process's group id.
6763[clinic start generated code]*/
6764
Larry Hastings2f936352014-08-05 14:04:04 +10006765static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006766os_setgid_impl(PyObject *module, gid_t gid)
6767/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006768{
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 if (setgid(gid) < 0)
6770 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006771 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006772}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006773#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006774
Larry Hastings2f936352014-08-05 14:04:04 +10006775
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006776#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006777/*[clinic input]
6778os.setgroups
6779
6780 groups: object
6781 /
6782
6783Set the groups of the current process to list.
6784[clinic start generated code]*/
6785
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006786static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006787os_setgroups(PyObject *module, PyObject *groups)
6788/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006789{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006790 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006792
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 if (!PySequence_Check(groups)) {
6794 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6795 return NULL;
6796 }
6797 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006798 if (len < 0) {
6799 return NULL;
6800 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 if (len > MAX_GROUPS) {
6802 PyErr_SetString(PyExc_ValueError, "too many groups");
6803 return NULL;
6804 }
6805 for(i = 0; i < len; i++) {
6806 PyObject *elem;
6807 elem = PySequence_GetItem(groups, i);
6808 if (!elem)
6809 return NULL;
6810 if (!PyLong_Check(elem)) {
6811 PyErr_SetString(PyExc_TypeError,
6812 "groups must be integers");
6813 Py_DECREF(elem);
6814 return NULL;
6815 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006816 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 Py_DECREF(elem);
6818 return NULL;
6819 }
6820 }
6821 Py_DECREF(elem);
6822 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006823
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 if (setgroups(len, grouplist) < 0)
6825 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006826 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006827}
6828#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006829
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006830#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6831static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006832wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006833{
Victor Stinner8c62be82010-05-06 00:08:46 +00006834 PyObject *result;
6835 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006836 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006837
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 if (pid == -1)
6839 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006840
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 if (struct_rusage == NULL) {
6842 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6843 if (m == NULL)
6844 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006845 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006846 Py_DECREF(m);
6847 if (struct_rusage == NULL)
6848 return NULL;
6849 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006850
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6852 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6853 if (!result)
6854 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006855
6856#ifndef doubletime
6857#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6858#endif
6859
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006861 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006863 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006864#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6866 SET_INT(result, 2, ru->ru_maxrss);
6867 SET_INT(result, 3, ru->ru_ixrss);
6868 SET_INT(result, 4, ru->ru_idrss);
6869 SET_INT(result, 5, ru->ru_isrss);
6870 SET_INT(result, 6, ru->ru_minflt);
6871 SET_INT(result, 7, ru->ru_majflt);
6872 SET_INT(result, 8, ru->ru_nswap);
6873 SET_INT(result, 9, ru->ru_inblock);
6874 SET_INT(result, 10, ru->ru_oublock);
6875 SET_INT(result, 11, ru->ru_msgsnd);
6876 SET_INT(result, 12, ru->ru_msgrcv);
6877 SET_INT(result, 13, ru->ru_nsignals);
6878 SET_INT(result, 14, ru->ru_nvcsw);
6879 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880#undef SET_INT
6881
Victor Stinner8c62be82010-05-06 00:08:46 +00006882 if (PyErr_Occurred()) {
6883 Py_DECREF(result);
6884 return NULL;
6885 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006886
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006888}
6889#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6890
Larry Hastings2f936352014-08-05 14:04:04 +10006891
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006892#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006893/*[clinic input]
6894os.wait3
6895
6896 options: int
6897Wait for completion of a child process.
6898
6899Returns a tuple of information about the child process:
6900 (pid, status, rusage)
6901[clinic start generated code]*/
6902
Larry Hastings2f936352014-08-05 14:04:04 +10006903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006904os_wait3_impl(PyObject *module, int options)
6905/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006906{
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006909 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 WAIT_TYPE status;
6911 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006912
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006913 do {
6914 Py_BEGIN_ALLOW_THREADS
6915 pid = wait3(&status, options, &ru);
6916 Py_END_ALLOW_THREADS
6917 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6918 if (pid < 0)
6919 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006920
Victor Stinner4195b5c2012-02-08 23:03:19 +01006921 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006922}
6923#endif /* HAVE_WAIT3 */
6924
Larry Hastings2f936352014-08-05 14:04:04 +10006925
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006926#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006927/*[clinic input]
6928
6929os.wait4
6930
6931 pid: pid_t
6932 options: int
6933
6934Wait for completion of a specific child process.
6935
6936Returns a tuple of information about the child process:
6937 (pid, status, rusage)
6938[clinic start generated code]*/
6939
Larry Hastings2f936352014-08-05 14:04:04 +10006940static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006941os_wait4_impl(PyObject *module, pid_t pid, int options)
6942/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006943{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006944 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006946 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 WAIT_TYPE status;
6948 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006949
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006950 do {
6951 Py_BEGIN_ALLOW_THREADS
6952 res = wait4(pid, &status, options, &ru);
6953 Py_END_ALLOW_THREADS
6954 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6955 if (res < 0)
6956 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006957
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006958 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006959}
6960#endif /* HAVE_WAIT4 */
6961
Larry Hastings2f936352014-08-05 14:04:04 +10006962
Ross Lagerwall7807c352011-03-17 20:20:30 +02006963#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006964/*[clinic input]
6965os.waitid
6966
6967 idtype: idtype_t
6968 Must be one of be P_PID, P_PGID or P_ALL.
6969 id: id_t
6970 The id to wait on.
6971 options: int
6972 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6973 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6974 /
6975
6976Returns the result of waiting for a process or processes.
6977
6978Returns either waitid_result or None if WNOHANG is specified and there are
6979no children in a waitable state.
6980[clinic start generated code]*/
6981
Larry Hastings2f936352014-08-05 14:04:04 +10006982static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006983os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6984/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006985{
6986 PyObject *result;
6987 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006988 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006989 siginfo_t si;
6990 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006991
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006992 do {
6993 Py_BEGIN_ALLOW_THREADS
6994 res = waitid(idtype, id, &si, options);
6995 Py_END_ALLOW_THREADS
6996 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6997 if (res < 0)
6998 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006999
7000 if (si.si_pid == 0)
7001 Py_RETURN_NONE;
7002
7003 result = PyStructSequence_New(&WaitidResultType);
7004 if (!result)
7005 return NULL;
7006
7007 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007008 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007009 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7010 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7011 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7012 if (PyErr_Occurred()) {
7013 Py_DECREF(result);
7014 return NULL;
7015 }
7016
7017 return result;
7018}
Larry Hastings2f936352014-08-05 14:04:04 +10007019#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007020
Larry Hastings2f936352014-08-05 14:04:04 +10007021
7022#if defined(HAVE_WAITPID)
7023/*[clinic input]
7024os.waitpid
7025 pid: pid_t
7026 options: int
7027 /
7028
7029Wait for completion of a given child process.
7030
7031Returns a tuple of information regarding the child process:
7032 (pid, status)
7033
7034The options argument is ignored on Windows.
7035[clinic start generated code]*/
7036
Larry Hastings2f936352014-08-05 14:04:04 +10007037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007038os_waitpid_impl(PyObject *module, pid_t pid, int options)
7039/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007040{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007041 pid_t res;
7042 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 WAIT_TYPE status;
7044 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007045
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007046 do {
7047 Py_BEGIN_ALLOW_THREADS
7048 res = waitpid(pid, &status, options);
7049 Py_END_ALLOW_THREADS
7050 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7051 if (res < 0)
7052 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007053
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007054 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007055}
Tim Petersab034fa2002-02-01 11:27:43 +00007056#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007057/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007058/*[clinic input]
7059os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007060 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007061 options: int
7062 /
7063
7064Wait for completion of a given process.
7065
7066Returns a tuple of information regarding the process:
7067 (pid, status << 8)
7068
7069The options argument is ignored on Windows.
7070[clinic start generated code]*/
7071
Larry Hastings2f936352014-08-05 14:04:04 +10007072static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007073os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007074/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007075{
7076 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007077 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007078 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007079
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007080 do {
7081 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007082 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007083 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007084 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007085 Py_END_ALLOW_THREADS
7086 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007087 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007088 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007089
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007091 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007092}
Larry Hastings2f936352014-08-05 14:04:04 +10007093#endif
7094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007095
Guido van Rossumad0ee831995-03-01 10:34:45 +00007096#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007097/*[clinic input]
7098os.wait
7099
7100Wait for completion of a child process.
7101
7102Returns a tuple of information about the child process:
7103 (pid, status)
7104[clinic start generated code]*/
7105
Larry Hastings2f936352014-08-05 14:04:04 +10007106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007107os_wait_impl(PyObject *module)
7108/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007109{
Victor Stinner8c62be82010-05-06 00:08:46 +00007110 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007111 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007112 WAIT_TYPE status;
7113 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007114
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007115 do {
7116 Py_BEGIN_ALLOW_THREADS
7117 pid = wait(&status);
7118 Py_END_ALLOW_THREADS
7119 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7120 if (pid < 0)
7121 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007122
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007124}
Larry Hastings2f936352014-08-05 14:04:04 +10007125#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007127
Larry Hastings9cf065c2012-06-22 16:30:09 -07007128#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7129PyDoc_STRVAR(readlink__doc__,
7130"readlink(path, *, dir_fd=None) -> path\n\n\
7131Return a string representing the path to which the symbolic link points.\n\
7132\n\
7133If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7134 and path should be relative; path will then be relative to that directory.\n\
7135dir_fd may not be implemented on your platform.\n\
7136 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007137#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007138
Guido van Rossumb6775db1994-08-01 11:34:53 +00007139#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007140
Larry Hastings2f936352014-08-05 14:04:04 +10007141/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007142static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007143posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007144{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007145 path_t path;
7146 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007147 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007148 ssize_t length;
7149 PyObject *return_value = NULL;
7150 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007151
Larry Hastings9cf065c2012-06-22 16:30:09 -07007152 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007153 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007154 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7155 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007156 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007157 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007158
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007160#ifdef HAVE_READLINKAT
7161 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007162 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007163 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007164#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007165 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007166 Py_END_ALLOW_THREADS
7167
7168 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007169 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170 goto exit;
7171 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007172 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007173
7174 if (PyUnicode_Check(path.object))
7175 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7176 else
7177 return_value = PyBytes_FromStringAndSize(buffer, length);
7178exit:
7179 path_cleanup(&path);
7180 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007181}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007182
Guido van Rossumb6775db1994-08-01 11:34:53 +00007183#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007184
Larry Hastings2f936352014-08-05 14:04:04 +10007185#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7186
7187static PyObject *
7188win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7189{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007190 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007191 DWORD n_bytes_returned;
7192 DWORD io_result;
7193 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007194 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007195 HANDLE reparse_point_handle;
7196
Martin Panter70214ad2016-08-04 02:38:59 +00007197 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7198 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007199 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007200
7201 static char *keywords[] = {"path", "dir_fd", NULL};
7202
7203 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7204 &po,
7205 dir_fd_unavailable, &dir_fd
7206 ))
7207 return NULL;
7208
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007209 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007210 if (path == NULL)
7211 return NULL;
7212
7213 /* First get a handle to the reparse point */
7214 Py_BEGIN_ALLOW_THREADS
7215 reparse_point_handle = CreateFileW(
7216 path,
7217 0,
7218 0,
7219 0,
7220 OPEN_EXISTING,
7221 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7222 0);
7223 Py_END_ALLOW_THREADS
7224
7225 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7226 return win32_error_object("readlink", po);
7227
7228 Py_BEGIN_ALLOW_THREADS
7229 /* New call DeviceIoControl to read the reparse point */
7230 io_result = DeviceIoControl(
7231 reparse_point_handle,
7232 FSCTL_GET_REPARSE_POINT,
7233 0, 0, /* in buffer */
7234 target_buffer, sizeof(target_buffer),
7235 &n_bytes_returned,
7236 0 /* we're not using OVERLAPPED_IO */
7237 );
7238 CloseHandle(reparse_point_handle);
7239 Py_END_ALLOW_THREADS
7240
7241 if (io_result==0)
7242 return win32_error_object("readlink", po);
7243
7244 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7245 {
7246 PyErr_SetString(PyExc_ValueError,
7247 "not a symbolic link");
7248 return NULL;
7249 }
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007250 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7251 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007252
7253 result = PyUnicode_FromWideChar(print_name,
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007254 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
Larry Hastings2f936352014-08-05 14:04:04 +10007255 return result;
7256}
7257
7258#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7259
7260
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007261
Larry Hastings9cf065c2012-06-22 16:30:09 -07007262#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007263
7264#if defined(MS_WINDOWS)
7265
7266/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007267static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007268
Larry Hastings9cf065c2012-06-22 16:30:09 -07007269static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007270check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007271{
7272 HINSTANCE hKernel32;
7273 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007274 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007275 return 1;
7276 hKernel32 = GetModuleHandleW(L"KERNEL32");
7277 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7278 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007279 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007280}
7281
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007282/* Remove the last portion of the path - return 0 on success */
7283static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007284_dirnameW(WCHAR *path)
7285{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007286 WCHAR *ptr;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007287 size_t length = wcsnlen_s(path, MAX_PATH);
7288 if (length == MAX_PATH) {
7289 return -1;
7290 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007291
7292 /* walk the path from the end until a backslash is encountered */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007293 for(ptr = path + length; ptr != path; ptr--) {
7294 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007295 break;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007296 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007297 }
7298 *ptr = 0;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007299 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007300}
7301
Victor Stinner31b3b922013-06-05 01:49:17 +02007302/* Is this path absolute? */
7303static int
7304_is_absW(const WCHAR *path)
7305{
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007306 return path[0] == L'\\' || path[0] == L'/' ||
7307 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007308}
7309
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007310/* join root and rest with a backslash - return 0 on success */
7311static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007312_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7313{
Victor Stinner31b3b922013-06-05 01:49:17 +02007314 if (_is_absW(rest)) {
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007315 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007316 }
7317
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007318 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7319 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007320 }
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007321
7322 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7323 return -1;
7324 }
7325
7326 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007327}
7328
Victor Stinner31b3b922013-06-05 01:49:17 +02007329/* Return True if the path at src relative to dest is a directory */
7330static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007331_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007332{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007333 WIN32_FILE_ATTRIBUTE_DATA src_info;
7334 WCHAR dest_parent[MAX_PATH];
7335 WCHAR src_resolved[MAX_PATH] = L"";
7336
7337 /* dest_parent = os.path.dirname(dest) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007338 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7339 _dirnameW(dest_parent)) {
7340 return 0;
7341 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007342 /* src_resolved = os.path.join(dest_parent, src) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007343 if (_joinW(src_resolved, dest_parent, src)) {
7344 return 0;
7345 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007346 return (
7347 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7348 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7349 );
7350}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007351#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007352
Larry Hastings2f936352014-08-05 14:04:04 +10007353
7354/*[clinic input]
7355os.symlink
7356 src: path_t
7357 dst: path_t
7358 target_is_directory: bool = False
7359 *
7360 dir_fd: dir_fd(requires='symlinkat')=None
7361
7362# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7363
7364Create a symbolic link pointing to src named dst.
7365
7366target_is_directory is required on Windows if the target is to be
7367 interpreted as a directory. (On Windows, symlink requires
7368 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7369 target_is_directory is ignored on non-Windows platforms.
7370
7371If dir_fd is not None, it should be a file descriptor open to a directory,
7372 and path should be relative; path will then be relative to that directory.
7373dir_fd may not be implemented on your platform.
7374 If it is unavailable, using it will raise a NotImplementedError.
7375
7376[clinic start generated code]*/
7377
Larry Hastings2f936352014-08-05 14:04:04 +10007378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007379os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007380 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007381/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007382{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007383#ifdef MS_WINDOWS
7384 DWORD result;
7385#else
7386 int result;
7387#endif
7388
Larry Hastings9cf065c2012-06-22 16:30:09 -07007389#ifdef MS_WINDOWS
7390 if (!check_CreateSymbolicLink()) {
7391 PyErr_SetString(PyExc_NotImplementedError,
7392 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007393 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007394 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007395 if (!win32_can_symlink) {
7396 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007397 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007398 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007399#endif
7400
Larry Hastings9cf065c2012-06-22 16:30:09 -07007401#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007402
Larry Hastings9cf065c2012-06-22 16:30:09 -07007403 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007404 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007405 /* if src is a directory, ensure target_is_directory==1 */
7406 target_is_directory |= _check_dirW(src->wide, dst->wide);
7407 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7408 target_is_directory);
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007409 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007410 Py_END_ALLOW_THREADS
7411
Larry Hastings2f936352014-08-05 14:04:04 +10007412 if (!result)
7413 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007414
7415#else
7416
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007417 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7418 PyErr_SetString(PyExc_ValueError,
7419 "symlink: src and dst must be the same type");
7420 return NULL;
7421 }
7422
Larry Hastings9cf065c2012-06-22 16:30:09 -07007423 Py_BEGIN_ALLOW_THREADS
7424#if HAVE_SYMLINKAT
7425 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007426 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007427 else
7428#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007429 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007430 Py_END_ALLOW_THREADS
7431
Larry Hastings2f936352014-08-05 14:04:04 +10007432 if (result)
7433 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007434#endif
7435
Larry Hastings2f936352014-08-05 14:04:04 +10007436 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007437}
7438#endif /* HAVE_SYMLINK */
7439
Larry Hastings9cf065c2012-06-22 16:30:09 -07007440
Brian Curtind40e6f72010-07-08 21:39:08 +00007441
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007442
Larry Hastings605a62d2012-06-24 04:33:36 -07007443static PyStructSequence_Field times_result_fields[] = {
7444 {"user", "user time"},
7445 {"system", "system time"},
7446 {"children_user", "user time of children"},
7447 {"children_system", "system time of children"},
7448 {"elapsed", "elapsed time since an arbitrary point in the past"},
7449 {NULL}
7450};
7451
7452PyDoc_STRVAR(times_result__doc__,
7453"times_result: Result from os.times().\n\n\
7454This object may be accessed either as a tuple of\n\
7455 (user, system, children_user, children_system, elapsed),\n\
7456or via the attributes user, system, children_user, children_system,\n\
7457and elapsed.\n\
7458\n\
7459See os.times for more information.");
7460
7461static PyStructSequence_Desc times_result_desc = {
7462 "times_result", /* name */
7463 times_result__doc__, /* doc */
7464 times_result_fields,
7465 5
7466};
7467
7468static PyTypeObject TimesResultType;
7469
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007470#ifdef MS_WINDOWS
7471#define HAVE_TIMES /* mandatory, for the method table */
7472#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007473
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007474#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007475
7476static PyObject *
7477build_times_result(double user, double system,
7478 double children_user, double children_system,
7479 double elapsed)
7480{
7481 PyObject *value = PyStructSequence_New(&TimesResultType);
7482 if (value == NULL)
7483 return NULL;
7484
7485#define SET(i, field) \
7486 { \
7487 PyObject *o = PyFloat_FromDouble(field); \
7488 if (!o) { \
7489 Py_DECREF(value); \
7490 return NULL; \
7491 } \
7492 PyStructSequence_SET_ITEM(value, i, o); \
7493 } \
7494
7495 SET(0, user);
7496 SET(1, system);
7497 SET(2, children_user);
7498 SET(3, children_system);
7499 SET(4, elapsed);
7500
7501#undef SET
7502
7503 return value;
7504}
7505
Larry Hastings605a62d2012-06-24 04:33:36 -07007506
Larry Hastings2f936352014-08-05 14:04:04 +10007507#ifndef MS_WINDOWS
7508#define NEED_TICKS_PER_SECOND
7509static long ticks_per_second = -1;
7510#endif /* MS_WINDOWS */
7511
7512/*[clinic input]
7513os.times
7514
7515Return a collection containing process timing information.
7516
7517The object returned behaves like a named tuple with these fields:
7518 (utime, stime, cutime, cstime, elapsed_time)
7519All fields are floating point numbers.
7520[clinic start generated code]*/
7521
Larry Hastings2f936352014-08-05 14:04:04 +10007522static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007523os_times_impl(PyObject *module)
7524/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007525#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007526{
Victor Stinner8c62be82010-05-06 00:08:46 +00007527 FILETIME create, exit, kernel, user;
7528 HANDLE hProc;
7529 hProc = GetCurrentProcess();
7530 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7531 /* The fields of a FILETIME structure are the hi and lo part
7532 of a 64-bit value expressed in 100 nanosecond units.
7533 1e7 is one second in such units; 1e-7 the inverse.
7534 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7535 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007536 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007537 (double)(user.dwHighDateTime*429.4967296 +
7538 user.dwLowDateTime*1e-7),
7539 (double)(kernel.dwHighDateTime*429.4967296 +
7540 kernel.dwLowDateTime*1e-7),
7541 (double)0,
7542 (double)0,
7543 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007544}
Larry Hastings2f936352014-08-05 14:04:04 +10007545#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007546{
Larry Hastings2f936352014-08-05 14:04:04 +10007547
7548
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007549 struct tms t;
7550 clock_t c;
7551 errno = 0;
7552 c = times(&t);
7553 if (c == (clock_t) -1)
7554 return posix_error();
7555 return build_times_result(
7556 (double)t.tms_utime / ticks_per_second,
7557 (double)t.tms_stime / ticks_per_second,
7558 (double)t.tms_cutime / ticks_per_second,
7559 (double)t.tms_cstime / ticks_per_second,
7560 (double)c / ticks_per_second);
7561}
Larry Hastings2f936352014-08-05 14:04:04 +10007562#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007563#endif /* HAVE_TIMES */
7564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007565
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007566#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007567/*[clinic input]
7568os.getsid
7569
7570 pid: pid_t
7571 /
7572
7573Call the system call getsid(pid) and return the result.
7574[clinic start generated code]*/
7575
Larry Hastings2f936352014-08-05 14:04:04 +10007576static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007577os_getsid_impl(PyObject *module, pid_t pid)
7578/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007579{
Victor Stinner8c62be82010-05-06 00:08:46 +00007580 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007581 sid = getsid(pid);
7582 if (sid < 0)
7583 return posix_error();
7584 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007585}
7586#endif /* HAVE_GETSID */
7587
7588
Guido van Rossumb6775db1994-08-01 11:34:53 +00007589#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007590/*[clinic input]
7591os.setsid
7592
7593Call the system call setsid().
7594[clinic start generated code]*/
7595
Larry Hastings2f936352014-08-05 14:04:04 +10007596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007597os_setsid_impl(PyObject *module)
7598/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007599{
Victor Stinner8c62be82010-05-06 00:08:46 +00007600 if (setsid() < 0)
7601 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007602 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007603}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007604#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007605
Larry Hastings2f936352014-08-05 14:04:04 +10007606
Guido van Rossumb6775db1994-08-01 11:34:53 +00007607#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007608/*[clinic input]
7609os.setpgid
7610
7611 pid: pid_t
7612 pgrp: pid_t
7613 /
7614
7615Call the system call setpgid(pid, pgrp).
7616[clinic start generated code]*/
7617
Larry Hastings2f936352014-08-05 14:04:04 +10007618static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007619os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7620/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007621{
Victor Stinner8c62be82010-05-06 00:08:46 +00007622 if (setpgid(pid, pgrp) < 0)
7623 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007624 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007625}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007626#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007627
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007628
Guido van Rossumb6775db1994-08-01 11:34:53 +00007629#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007630/*[clinic input]
7631os.tcgetpgrp
7632
7633 fd: int
7634 /
7635
7636Return the process group associated with the terminal specified by fd.
7637[clinic start generated code]*/
7638
Larry Hastings2f936352014-08-05 14:04:04 +10007639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007640os_tcgetpgrp_impl(PyObject *module, int fd)
7641/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007642{
7643 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007644 if (pgid < 0)
7645 return posix_error();
7646 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007647}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007648#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007649
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007650
Guido van Rossumb6775db1994-08-01 11:34:53 +00007651#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007652/*[clinic input]
7653os.tcsetpgrp
7654
7655 fd: int
7656 pgid: pid_t
7657 /
7658
7659Set the process group associated with the terminal specified by fd.
7660[clinic start generated code]*/
7661
Larry Hastings2f936352014-08-05 14:04:04 +10007662static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007663os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7664/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007665{
Victor Stinner8c62be82010-05-06 00:08:46 +00007666 if (tcsetpgrp(fd, pgid) < 0)
7667 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007668 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007669}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007670#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007671
Guido van Rossum687dd131993-05-17 08:34:16 +00007672/* Functions acting on file descriptors */
7673
Victor Stinnerdaf45552013-08-28 00:53:59 +02007674#ifdef O_CLOEXEC
7675extern int _Py_open_cloexec_works;
7676#endif
7677
Larry Hastings2f936352014-08-05 14:04:04 +10007678
7679/*[clinic input]
7680os.open -> int
7681 path: path_t
7682 flags: int
7683 mode: int = 0o777
7684 *
7685 dir_fd: dir_fd(requires='openat') = None
7686
7687# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7688
7689Open a file for low level IO. Returns a file descriptor (integer).
7690
7691If dir_fd is not None, it should be a file descriptor open to a directory,
7692 and path should be relative; path will then be relative to that directory.
7693dir_fd may not be implemented on your platform.
7694 If it is unavailable, using it will raise a NotImplementedError.
7695[clinic start generated code]*/
7696
Larry Hastings2f936352014-08-05 14:04:04 +10007697static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007698os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7699/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007700{
7701 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007702 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007703
Victor Stinnerdaf45552013-08-28 00:53:59 +02007704#ifdef O_CLOEXEC
7705 int *atomic_flag_works = &_Py_open_cloexec_works;
7706#elif !defined(MS_WINDOWS)
7707 int *atomic_flag_works = NULL;
7708#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007709
Victor Stinnerdaf45552013-08-28 00:53:59 +02007710#ifdef MS_WINDOWS
7711 flags |= O_NOINHERIT;
7712#elif defined(O_CLOEXEC)
7713 flags |= O_CLOEXEC;
7714#endif
7715
Steve Dower8fc89802015-04-12 00:26:27 -04007716 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007717 do {
7718 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007719#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007720 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007721#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007722#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007723 if (dir_fd != DEFAULT_DIR_FD)
7724 fd = openat(dir_fd, path->narrow, flags, mode);
7725 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007726#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007727 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007728#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007729 Py_END_ALLOW_THREADS
7730 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007731 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007732
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007733 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007734 if (!async_err)
7735 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007736 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007737 }
7738
Victor Stinnerdaf45552013-08-28 00:53:59 +02007739#ifndef MS_WINDOWS
7740 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7741 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007742 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007743 }
7744#endif
7745
Larry Hastings2f936352014-08-05 14:04:04 +10007746 return fd;
7747}
7748
7749
7750/*[clinic input]
7751os.close
7752
7753 fd: int
7754
7755Close a file descriptor.
7756[clinic start generated code]*/
7757
Barry Warsaw53699e91996-12-10 23:23:01 +00007758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007759os_close_impl(PyObject *module, int fd)
7760/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007761{
Larry Hastings2f936352014-08-05 14:04:04 +10007762 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007763 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7764 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7765 * for more details.
7766 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007768 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007770 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007771 Py_END_ALLOW_THREADS
7772 if (res < 0)
7773 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007774 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007775}
7776
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007777
Larry Hastings2f936352014-08-05 14:04:04 +10007778/*[clinic input]
7779os.closerange
7780
7781 fd_low: int
7782 fd_high: int
7783 /
7784
7785Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7786[clinic start generated code]*/
7787
Larry Hastings2f936352014-08-05 14:04:04 +10007788static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007789os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7790/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007791{
7792 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007794 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007795 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007796 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007797 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 Py_END_ALLOW_THREADS
7799 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007800}
7801
7802
Larry Hastings2f936352014-08-05 14:04:04 +10007803/*[clinic input]
7804os.dup -> int
7805
7806 fd: int
7807 /
7808
7809Return a duplicate of a file descriptor.
7810[clinic start generated code]*/
7811
Larry Hastings2f936352014-08-05 14:04:04 +10007812static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007813os_dup_impl(PyObject *module, int fd)
7814/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007815{
7816 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007817}
7818
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007819
Larry Hastings2f936352014-08-05 14:04:04 +10007820/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007821os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10007822 fd: int
7823 fd2: int
7824 inheritable: bool=True
7825
7826Duplicate file descriptor.
7827[clinic start generated code]*/
7828
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007829static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007830os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007831/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007832{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01007833 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007834#if defined(HAVE_DUP3) && \
7835 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7836 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Miss Islington (bot)bab4fe32018-02-19 23:46:47 -08007837 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007838#endif
7839
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007840 if (fd < 0 || fd2 < 0) {
7841 posix_error();
7842 return -1;
7843 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007844
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007845 /* dup2() can fail with EINTR if the target FD is already open, because it
7846 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7847 * upon close(), and therefore below.
7848 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007849#ifdef MS_WINDOWS
7850 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007851 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007852 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007853 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007854 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007855 if (res < 0) {
7856 posix_error();
7857 return -1;
7858 }
7859 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02007860
7861 /* Character files like console cannot be make non-inheritable */
7862 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7863 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007864 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007865 }
7866
7867#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7868 Py_BEGIN_ALLOW_THREADS
7869 if (!inheritable)
7870 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7871 else
7872 res = dup2(fd, fd2);
7873 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007874 if (res < 0) {
7875 posix_error();
7876 return -1;
7877 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007878
7879#else
7880
7881#ifdef HAVE_DUP3
7882 if (!inheritable && dup3_works != 0) {
7883 Py_BEGIN_ALLOW_THREADS
7884 res = dup3(fd, fd2, O_CLOEXEC);
7885 Py_END_ALLOW_THREADS
7886 if (res < 0) {
7887 if (dup3_works == -1)
7888 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007889 if (dup3_works) {
7890 posix_error();
7891 return -1;
7892 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007893 }
7894 }
7895
7896 if (inheritable || dup3_works == 0)
7897 {
7898#endif
7899 Py_BEGIN_ALLOW_THREADS
7900 res = dup2(fd, fd2);
7901 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007902 if (res < 0) {
7903 posix_error();
7904 return -1;
7905 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007906
7907 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7908 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007909 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007910 }
7911#ifdef HAVE_DUP3
7912 }
7913#endif
7914
7915#endif
7916
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007917 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00007918}
7919
Larry Hastings2f936352014-08-05 14:04:04 +10007920
Ross Lagerwall7807c352011-03-17 20:20:30 +02007921#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007922/*[clinic input]
7923os.lockf
7924
7925 fd: int
7926 An open file descriptor.
7927 command: int
7928 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7929 length: Py_off_t
7930 The number of bytes to lock, starting at the current position.
7931 /
7932
7933Apply, test or remove a POSIX lock on an open file descriptor.
7934
7935[clinic start generated code]*/
7936
Larry Hastings2f936352014-08-05 14:04:04 +10007937static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007938os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7939/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007940{
7941 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007942
7943 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007944 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007945 Py_END_ALLOW_THREADS
7946
7947 if (res < 0)
7948 return posix_error();
7949
7950 Py_RETURN_NONE;
7951}
Larry Hastings2f936352014-08-05 14:04:04 +10007952#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007953
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007954
Larry Hastings2f936352014-08-05 14:04:04 +10007955/*[clinic input]
7956os.lseek -> Py_off_t
7957
7958 fd: int
7959 position: Py_off_t
7960 how: int
7961 /
7962
7963Set the position of a file descriptor. Return the new position.
7964
7965Return the new cursor position in number of bytes
7966relative to the beginning of the file.
7967[clinic start generated code]*/
7968
Larry Hastings2f936352014-08-05 14:04:04 +10007969static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007970os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7971/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007972{
7973 Py_off_t result;
7974
Guido van Rossum687dd131993-05-17 08:34:16 +00007975#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7977 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007978 case 0: how = SEEK_SET; break;
7979 case 1: how = SEEK_CUR; break;
7980 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007982#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007983
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007985 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007986
Victor Stinner8c62be82010-05-06 00:08:46 +00007987 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007988 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007989#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007990 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007991#else
Larry Hastings2f936352014-08-05 14:04:04 +10007992 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007993#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007994 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007996 if (result < 0)
7997 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007998
Larry Hastings2f936352014-08-05 14:04:04 +10007999 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008000}
8001
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008002
Larry Hastings2f936352014-08-05 14:04:04 +10008003/*[clinic input]
8004os.read
8005 fd: int
8006 length: Py_ssize_t
8007 /
8008
8009Read from a file descriptor. Returns a bytes object.
8010[clinic start generated code]*/
8011
Larry Hastings2f936352014-08-05 14:04:04 +10008012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008013os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8014/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008015{
Victor Stinner8c62be82010-05-06 00:08:46 +00008016 Py_ssize_t n;
8017 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008018
8019 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008020 errno = EINVAL;
8021 return posix_error();
8022 }
Larry Hastings2f936352014-08-05 14:04:04 +10008023
Miss Islington (bot)18f33272018-11-22 06:17:34 -08008024 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008025
8026 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008027 if (buffer == NULL)
8028 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008029
Victor Stinner66aab0c2015-03-19 22:53:20 +01008030 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8031 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008033 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008034 }
Larry Hastings2f936352014-08-05 14:04:04 +10008035
8036 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008038
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008040}
8041
Ross Lagerwall7807c352011-03-17 20:20:30 +02008042#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008043 || defined(__APPLE__))) \
8044 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8045 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8046static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008047iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008048{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008049 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008050
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008051 *iov = PyMem_New(struct iovec, cnt);
8052 if (*iov == NULL) {
8053 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008054 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008055 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008056
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008057 *buf = PyMem_New(Py_buffer, cnt);
8058 if (*buf == NULL) {
8059 PyMem_Del(*iov);
8060 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008061 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008062 }
8063
8064 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008065 PyObject *item = PySequence_GetItem(seq, i);
8066 if (item == NULL)
8067 goto fail;
8068 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8069 Py_DECREF(item);
8070 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008071 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008072 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008073 (*iov)[i].iov_base = (*buf)[i].buf;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008074 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075 }
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008076 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008077
8078fail:
8079 PyMem_Del(*iov);
8080 for (j = 0; j < i; j++) {
8081 PyBuffer_Release(&(*buf)[j]);
8082 }
8083 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008084 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008085}
8086
8087static void
8088iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8089{
8090 int i;
8091 PyMem_Del(iov);
8092 for (i = 0; i < cnt; i++) {
8093 PyBuffer_Release(&buf[i]);
8094 }
8095 PyMem_Del(buf);
8096}
8097#endif
8098
Larry Hastings2f936352014-08-05 14:04:04 +10008099
Ross Lagerwall7807c352011-03-17 20:20:30 +02008100#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008101/*[clinic input]
8102os.readv -> Py_ssize_t
8103
8104 fd: int
8105 buffers: object
8106 /
8107
8108Read from a file descriptor fd into an iterable of buffers.
8109
8110The buffers should be mutable buffers accepting bytes.
8111readv will transfer data into each buffer until it is full
8112and then move on to the next buffer in the sequence to hold
8113the rest of the data.
8114
8115readv returns the total number of bytes read,
8116which may be less than the total capacity of all the buffers.
8117[clinic start generated code]*/
8118
Larry Hastings2f936352014-08-05 14:04:04 +10008119static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008120os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8121/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008122{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008123 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008124 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008125 struct iovec *iov;
8126 Py_buffer *buf;
8127
Larry Hastings2f936352014-08-05 14:04:04 +10008128 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008129 PyErr_SetString(PyExc_TypeError,
8130 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008131 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008132 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008133
Larry Hastings2f936352014-08-05 14:04:04 +10008134 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008135 if (cnt < 0)
8136 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008137
8138 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8139 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008140
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008141 do {
8142 Py_BEGIN_ALLOW_THREADS
8143 n = readv(fd, iov, cnt);
8144 Py_END_ALLOW_THREADS
8145 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008146
8147 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008148 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008149 if (!async_err)
8150 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008151 return -1;
8152 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008153
Larry Hastings2f936352014-08-05 14:04:04 +10008154 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008155}
Larry Hastings2f936352014-08-05 14:04:04 +10008156#endif /* HAVE_READV */
8157
Ross Lagerwall7807c352011-03-17 20:20:30 +02008158
8159#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008160/*[clinic input]
8161# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8162os.pread
8163
8164 fd: int
8165 length: int
8166 offset: Py_off_t
8167 /
8168
8169Read a number of bytes from a file descriptor starting at a particular offset.
8170
8171Read length bytes from file descriptor fd, starting at offset bytes from
8172the beginning of the file. The file offset remains unchanged.
8173[clinic start generated code]*/
8174
Larry Hastings2f936352014-08-05 14:04:04 +10008175static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008176os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8177/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008178{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008179 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008180 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008181 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008182
Larry Hastings2f936352014-08-05 14:04:04 +10008183 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008184 errno = EINVAL;
8185 return posix_error();
8186 }
Larry Hastings2f936352014-08-05 14:04:04 +10008187 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008188 if (buffer == NULL)
8189 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008190
8191 do {
8192 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008193 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008194 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008195 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008196 Py_END_ALLOW_THREADS
8197 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8198
Ross Lagerwall7807c352011-03-17 20:20:30 +02008199 if (n < 0) {
8200 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008201 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008202 }
Larry Hastings2f936352014-08-05 14:04:04 +10008203 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008204 _PyBytes_Resize(&buffer, n);
8205 return buffer;
8206}
Larry Hastings2f936352014-08-05 14:04:04 +10008207#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008208
Pablo Galindo4defba32018-01-27 16:16:37 +00008209#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8210/*[clinic input]
8211os.preadv -> Py_ssize_t
8212
8213 fd: int
8214 buffers: object
8215 offset: Py_off_t
8216 flags: int = 0
8217 /
8218
8219Reads from a file descriptor into a number of mutable bytes-like objects.
8220
8221Combines the functionality of readv() and pread(). As readv(), it will
8222transfer data into each buffer until it is full and then move on to the next
8223buffer in the sequence to hold the rest of the data. Its fourth argument,
8224specifies the file offset at which the input operation is to be performed. It
8225will return the total number of bytes read (which can be less than the total
8226capacity of all the objects).
8227
8228The flags argument contains a bitwise OR of zero or more of the following flags:
8229
8230- RWF_HIPRI
8231- RWF_NOWAIT
8232
8233Using non-zero flags requires Linux 4.6 or newer.
8234[clinic start generated code]*/
8235
8236static Py_ssize_t
8237os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8238 int flags)
8239/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8240{
8241 Py_ssize_t cnt, n;
8242 int async_err = 0;
8243 struct iovec *iov;
8244 Py_buffer *buf;
8245
8246 if (!PySequence_Check(buffers)) {
8247 PyErr_SetString(PyExc_TypeError,
8248 "preadv2() arg 2 must be a sequence");
8249 return -1;
8250 }
8251
8252 cnt = PySequence_Size(buffers);
8253 if (cnt < 0) {
8254 return -1;
8255 }
8256
8257#ifndef HAVE_PREADV2
8258 if(flags != 0) {
8259 argument_unavailable_error("preadv2", "flags");
8260 return -1;
8261 }
8262#endif
8263
8264 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8265 return -1;
8266 }
8267#ifdef HAVE_PREADV2
8268 do {
8269 Py_BEGIN_ALLOW_THREADS
8270 _Py_BEGIN_SUPPRESS_IPH
8271 n = preadv2(fd, iov, cnt, offset, flags);
8272 _Py_END_SUPPRESS_IPH
8273 Py_END_ALLOW_THREADS
8274 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8275#else
8276 do {
8277 Py_BEGIN_ALLOW_THREADS
8278 _Py_BEGIN_SUPPRESS_IPH
8279 n = preadv(fd, iov, cnt, offset);
8280 _Py_END_SUPPRESS_IPH
8281 Py_END_ALLOW_THREADS
8282 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8283#endif
8284
8285 iov_cleanup(iov, buf, cnt);
8286 if (n < 0) {
8287 if (!async_err) {
8288 posix_error();
8289 }
8290 return -1;
8291 }
8292
8293 return n;
8294}
8295#endif /* HAVE_PREADV */
8296
Larry Hastings2f936352014-08-05 14:04:04 +10008297
8298/*[clinic input]
8299os.write -> Py_ssize_t
8300
8301 fd: int
8302 data: Py_buffer
8303 /
8304
8305Write a bytes object to a file descriptor.
8306[clinic start generated code]*/
8307
Larry Hastings2f936352014-08-05 14:04:04 +10008308static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008309os_write_impl(PyObject *module, int fd, Py_buffer *data)
8310/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008311{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008312 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008313}
8314
8315#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008316PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008317"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008318sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008319 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008320Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321
Larry Hastings2f936352014-08-05 14:04:04 +10008322/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008323static PyObject *
8324posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8325{
8326 int in, out;
8327 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008328 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008329 off_t offset;
8330
8331#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8332#ifndef __APPLE__
8333 Py_ssize_t len;
8334#endif
8335 PyObject *headers = NULL, *trailers = NULL;
8336 Py_buffer *hbuf, *tbuf;
8337 off_t sbytes;
8338 struct sf_hdtr sf;
8339 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008340 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008341 static char *keywords[] = {"out", "in",
8342 "offset", "count",
8343 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008344
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008345 sf.headers = NULL;
8346 sf.trailers = NULL;
8347
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008348#ifdef __APPLE__
8349 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008350 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008351#else
8352 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008353 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008354#endif
8355 &headers, &trailers, &flags))
8356 return NULL;
8357 if (headers != NULL) {
8358 if (!PySequence_Check(headers)) {
8359 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008360 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008361 return NULL;
8362 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008363 Py_ssize_t i = PySequence_Size(headers);
8364 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008365 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008366 if (i > INT_MAX) {
8367 PyErr_SetString(PyExc_OverflowError,
8368 "sendfile() header is too large");
8369 return NULL;
8370 }
8371 if (i > 0) {
8372 sf.hdr_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008373 if (iov_setup(&(sf.headers), &hbuf,
8374 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008375 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008376#ifdef __APPLE__
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008377 for (i = 0; i < sf.hdr_cnt; i++) {
8378 Py_ssize_t blen = sf.headers[i].iov_len;
8379# define OFF_T_MAX 0x7fffffffffffffff
8380 if (sbytes >= OFF_T_MAX - blen) {
8381 PyErr_SetString(PyExc_OverflowError,
8382 "sendfile() header is too large");
8383 return NULL;
8384 }
8385 sbytes += blen;
8386 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008387#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008388 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008389 }
8390 }
8391 if (trailers != NULL) {
8392 if (!PySequence_Check(trailers)) {
8393 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008394 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008395 return NULL;
8396 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008397 Py_ssize_t i = PySequence_Size(trailers);
8398 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008399 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008400 if (i > INT_MAX) {
8401 PyErr_SetString(PyExc_OverflowError,
8402 "sendfile() trailer is too large");
8403 return NULL;
8404 }
8405 if (i > 0) {
8406 sf.trl_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008407 if (iov_setup(&(sf.trailers), &tbuf,
8408 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008409 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008410 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008411 }
8412 }
8413
Steve Dower8fc89802015-04-12 00:26:27 -04008414 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008415 do {
8416 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008417#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008418 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008419#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008420 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008421#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008422 Py_END_ALLOW_THREADS
8423 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008424 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008425
8426 if (sf.headers != NULL)
8427 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8428 if (sf.trailers != NULL)
8429 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8430
8431 if (ret < 0) {
8432 if ((errno == EAGAIN) || (errno == EBUSY)) {
8433 if (sbytes != 0) {
8434 // some data has been sent
8435 goto done;
8436 }
8437 else {
8438 // no data has been sent; upper application is supposed
8439 // to retry on EAGAIN or EBUSY
8440 return posix_error();
8441 }
8442 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008443 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008444 }
8445 goto done;
8446
8447done:
8448 #if !defined(HAVE_LARGEFILE_SUPPORT)
8449 return Py_BuildValue("l", sbytes);
8450 #else
8451 return Py_BuildValue("L", sbytes);
8452 #endif
8453
8454#else
8455 Py_ssize_t count;
8456 PyObject *offobj;
8457 static char *keywords[] = {"out", "in",
8458 "offset", "count", NULL};
8459 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8460 keywords, &out, &in, &offobj, &count))
8461 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008462#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008463 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008464 do {
8465 Py_BEGIN_ALLOW_THREADS
8466 ret = sendfile(out, in, NULL, count);
8467 Py_END_ALLOW_THREADS
8468 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008469 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008470 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008471 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008472 }
8473#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008474 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008475 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008476
8477 do {
8478 Py_BEGIN_ALLOW_THREADS
8479 ret = sendfile(out, in, &offset, count);
8480 Py_END_ALLOW_THREADS
8481 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008482 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008483 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008484 return Py_BuildValue("n", ret);
8485#endif
8486}
Larry Hastings2f936352014-08-05 14:04:04 +10008487#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008488
Larry Hastings2f936352014-08-05 14:04:04 +10008489
8490/*[clinic input]
8491os.fstat
8492
8493 fd : int
8494
8495Perform a stat system call on the given file descriptor.
8496
8497Like stat(), but for an open file descriptor.
8498Equivalent to os.stat(fd).
8499[clinic start generated code]*/
8500
Larry Hastings2f936352014-08-05 14:04:04 +10008501static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008502os_fstat_impl(PyObject *module, int fd)
8503/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008504{
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 STRUCT_STAT st;
8506 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008507 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008508
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008509 do {
8510 Py_BEGIN_ALLOW_THREADS
8511 res = FSTAT(fd, &st);
8512 Py_END_ALLOW_THREADS
8513 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008514 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008515#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008516 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008517#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008518 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008519#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 }
Tim Peters5aa91602002-01-30 05:46:57 +00008521
Victor Stinner4195b5c2012-02-08 23:03:19 +01008522 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008523}
8524
Larry Hastings2f936352014-08-05 14:04:04 +10008525
8526/*[clinic input]
8527os.isatty -> bool
8528 fd: int
8529 /
8530
8531Return True if the fd is connected to a terminal.
8532
8533Return True if the file descriptor is an open file descriptor
8534connected to the slave end of a terminal.
8535[clinic start generated code]*/
8536
Larry Hastings2f936352014-08-05 14:04:04 +10008537static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008538os_isatty_impl(PyObject *module, int fd)
8539/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008540{
Steve Dower8fc89802015-04-12 00:26:27 -04008541 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008542 _Py_BEGIN_SUPPRESS_IPH
8543 return_value = isatty(fd);
8544 _Py_END_SUPPRESS_IPH
8545 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008546}
8547
8548
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008549#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008550/*[clinic input]
8551os.pipe
8552
8553Create a pipe.
8554
8555Returns a tuple of two file descriptors:
8556 (read_fd, write_fd)
8557[clinic start generated code]*/
8558
Larry Hastings2f936352014-08-05 14:04:04 +10008559static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008560os_pipe_impl(PyObject *module)
8561/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008562{
Victor Stinner8c62be82010-05-06 00:08:46 +00008563 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008564#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008565 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008566 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008567 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008568#else
8569 int res;
8570#endif
8571
8572#ifdef MS_WINDOWS
8573 attr.nLength = sizeof(attr);
8574 attr.lpSecurityDescriptor = NULL;
8575 attr.bInheritHandle = FALSE;
8576
8577 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008578 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008579 ok = CreatePipe(&read, &write, &attr, 0);
8580 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008581 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8582 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008583 if (fds[0] == -1 || fds[1] == -1) {
8584 CloseHandle(read);
8585 CloseHandle(write);
8586 ok = 0;
8587 }
8588 }
Steve Dowerc3630612016-11-19 18:41:16 -08008589 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008590 Py_END_ALLOW_THREADS
8591
Victor Stinner8c62be82010-05-06 00:08:46 +00008592 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008593 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008594#else
8595
8596#ifdef HAVE_PIPE2
8597 Py_BEGIN_ALLOW_THREADS
8598 res = pipe2(fds, O_CLOEXEC);
8599 Py_END_ALLOW_THREADS
8600
8601 if (res != 0 && errno == ENOSYS)
8602 {
8603#endif
8604 Py_BEGIN_ALLOW_THREADS
8605 res = pipe(fds);
8606 Py_END_ALLOW_THREADS
8607
8608 if (res == 0) {
8609 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8610 close(fds[0]);
8611 close(fds[1]);
8612 return NULL;
8613 }
8614 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8615 close(fds[0]);
8616 close(fds[1]);
8617 return NULL;
8618 }
8619 }
8620#ifdef HAVE_PIPE2
8621 }
8622#endif
8623
8624 if (res != 0)
8625 return PyErr_SetFromErrno(PyExc_OSError);
8626#endif /* !MS_WINDOWS */
8627 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008628}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008629#endif /* HAVE_PIPE */
8630
Larry Hastings2f936352014-08-05 14:04:04 +10008631
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008632#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008633/*[clinic input]
8634os.pipe2
8635
8636 flags: int
8637 /
8638
8639Create a pipe with flags set atomically.
8640
8641Returns a tuple of two file descriptors:
8642 (read_fd, write_fd)
8643
8644flags can be constructed by ORing together one or more of these values:
8645O_NONBLOCK, O_CLOEXEC.
8646[clinic start generated code]*/
8647
Larry Hastings2f936352014-08-05 14:04:04 +10008648static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008649os_pipe2_impl(PyObject *module, int flags)
8650/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008651{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008652 int fds[2];
8653 int res;
8654
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008655 res = pipe2(fds, flags);
8656 if (res != 0)
8657 return posix_error();
8658 return Py_BuildValue("(ii)", fds[0], fds[1]);
8659}
8660#endif /* HAVE_PIPE2 */
8661
Larry Hastings2f936352014-08-05 14:04:04 +10008662
Ross Lagerwall7807c352011-03-17 20:20:30 +02008663#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008664/*[clinic input]
8665os.writev -> Py_ssize_t
8666 fd: int
8667 buffers: object
8668 /
8669
8670Iterate over buffers, and write the contents of each to a file descriptor.
8671
8672Returns the total number of bytes written.
8673buffers must be a sequence of bytes-like objects.
8674[clinic start generated code]*/
8675
Larry Hastings2f936352014-08-05 14:04:04 +10008676static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008677os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8678/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008679{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008680 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008681 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008682 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008683 struct iovec *iov;
8684 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008685
8686 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008687 PyErr_SetString(PyExc_TypeError,
8688 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008689 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008690 }
Larry Hastings2f936352014-08-05 14:04:04 +10008691 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008692 if (cnt < 0)
8693 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008694
Larry Hastings2f936352014-08-05 14:04:04 +10008695 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8696 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008697 }
8698
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008699 do {
8700 Py_BEGIN_ALLOW_THREADS
8701 result = writev(fd, iov, cnt);
8702 Py_END_ALLOW_THREADS
8703 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008704
8705 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008706 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008707 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008708
Georg Brandl306336b2012-06-24 12:55:33 +02008709 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008710}
Larry Hastings2f936352014-08-05 14:04:04 +10008711#endif /* HAVE_WRITEV */
8712
8713
8714#ifdef HAVE_PWRITE
8715/*[clinic input]
8716os.pwrite -> Py_ssize_t
8717
8718 fd: int
8719 buffer: Py_buffer
8720 offset: Py_off_t
8721 /
8722
8723Write bytes to a file descriptor starting at a particular offset.
8724
8725Write buffer to fd, starting at offset bytes from the beginning of
8726the file. Returns the number of bytes writte. Does not change the
8727current file offset.
8728[clinic start generated code]*/
8729
Larry Hastings2f936352014-08-05 14:04:04 +10008730static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008731os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8732/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008733{
8734 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008735 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008736
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008737 do {
8738 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008739 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008740 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008741 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008742 Py_END_ALLOW_THREADS
8743 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008744
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008745 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008746 posix_error();
8747 return size;
8748}
8749#endif /* HAVE_PWRITE */
8750
Pablo Galindo4defba32018-01-27 16:16:37 +00008751#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8752/*[clinic input]
8753os.pwritev -> Py_ssize_t
8754
8755 fd: int
8756 buffers: object
8757 offset: Py_off_t
8758 flags: int = 0
8759 /
8760
8761Writes the contents of bytes-like objects to a file descriptor at a given offset.
8762
8763Combines the functionality of writev() and pwrite(). All buffers must be a sequence
8764of bytes-like objects. Buffers are processed in array order. Entire contents of first
8765buffer is written before proceeding to second, and so on. The operating system may
8766set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
8767This function writes the contents of each object to the file descriptor and returns
8768the total number of bytes written.
8769
8770The flags argument contains a bitwise OR of zero or more of the following flags:
8771
8772- RWF_DSYNC
8773- RWF_SYNC
8774
8775Using non-zero flags requires Linux 4.7 or newer.
8776[clinic start generated code]*/
8777
8778static Py_ssize_t
8779os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8780 int flags)
8781/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
8782{
8783 Py_ssize_t cnt;
8784 Py_ssize_t result;
8785 int async_err = 0;
8786 struct iovec *iov;
8787 Py_buffer *buf;
8788
8789 if (!PySequence_Check(buffers)) {
8790 PyErr_SetString(PyExc_TypeError,
8791 "pwritev() arg 2 must be a sequence");
8792 return -1;
8793 }
8794
8795 cnt = PySequence_Size(buffers);
8796 if (cnt < 0) {
8797 return -1;
8798 }
8799
8800#ifndef HAVE_PWRITEV2
8801 if(flags != 0) {
8802 argument_unavailable_error("pwritev2", "flags");
8803 return -1;
8804 }
8805#endif
8806
8807 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8808 return -1;
8809 }
8810#ifdef HAVE_PWRITEV2
8811 do {
8812 Py_BEGIN_ALLOW_THREADS
8813 _Py_BEGIN_SUPPRESS_IPH
8814 result = pwritev2(fd, iov, cnt, offset, flags);
8815 _Py_END_SUPPRESS_IPH
8816 Py_END_ALLOW_THREADS
8817 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8818#else
8819 do {
8820 Py_BEGIN_ALLOW_THREADS
8821 _Py_BEGIN_SUPPRESS_IPH
8822 result = pwritev(fd, iov, cnt, offset);
8823 _Py_END_SUPPRESS_IPH
8824 Py_END_ALLOW_THREADS
8825 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8826#endif
8827
8828 iov_cleanup(iov, buf, cnt);
8829 if (result < 0) {
8830 if (!async_err) {
8831 posix_error();
8832 }
8833 return -1;
8834 }
8835
8836 return result;
8837}
8838#endif /* HAVE_PWRITEV */
8839
8840
8841
Larry Hastings2f936352014-08-05 14:04:04 +10008842
8843#ifdef HAVE_MKFIFO
8844/*[clinic input]
8845os.mkfifo
8846
8847 path: path_t
8848 mode: int=0o666
8849 *
8850 dir_fd: dir_fd(requires='mkfifoat')=None
8851
8852Create a "fifo" (a POSIX named pipe).
8853
8854If dir_fd is not None, it should be a file descriptor open to a directory,
8855 and path should be relative; path will then be relative to that directory.
8856dir_fd may not be implemented on your platform.
8857 If it is unavailable, using it will raise a NotImplementedError.
8858[clinic start generated code]*/
8859
Larry Hastings2f936352014-08-05 14:04:04 +10008860static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008861os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8862/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008863{
8864 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008865 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008866
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008867 do {
8868 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008869#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008870 if (dir_fd != DEFAULT_DIR_FD)
8871 result = mkfifoat(dir_fd, path->narrow, mode);
8872 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008873#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008874 result = mkfifo(path->narrow, mode);
8875 Py_END_ALLOW_THREADS
8876 } while (result != 0 && errno == EINTR &&
8877 !(async_err = PyErr_CheckSignals()));
8878 if (result != 0)
8879 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008880
8881 Py_RETURN_NONE;
8882}
8883#endif /* HAVE_MKFIFO */
8884
8885
8886#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8887/*[clinic input]
8888os.mknod
8889
8890 path: path_t
8891 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008892 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008893 *
8894 dir_fd: dir_fd(requires='mknodat')=None
8895
8896Create a node in the file system.
8897
8898Create a node in the file system (file, device special file or named pipe)
8899at path. mode specifies both the permissions to use and the
8900type of node to be created, being combined (bitwise OR) with one of
8901S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8902device defines the newly created device special file (probably using
8903os.makedev()). Otherwise device is ignored.
8904
8905If dir_fd is not None, it should be a file descriptor open to a directory,
8906 and path should be relative; path will then be relative to that directory.
8907dir_fd may not be implemented on your platform.
8908 If it is unavailable, using it will raise a NotImplementedError.
8909[clinic start generated code]*/
8910
Larry Hastings2f936352014-08-05 14:04:04 +10008911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008912os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008913 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008914/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008915{
8916 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008917 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008918
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008919 do {
8920 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008921#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008922 if (dir_fd != DEFAULT_DIR_FD)
8923 result = mknodat(dir_fd, path->narrow, mode, device);
8924 else
Larry Hastings2f936352014-08-05 14:04:04 +10008925#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008926 result = mknod(path->narrow, mode, device);
8927 Py_END_ALLOW_THREADS
8928 } while (result != 0 && errno == EINTR &&
8929 !(async_err = PyErr_CheckSignals()));
8930 if (result != 0)
8931 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008932
8933 Py_RETURN_NONE;
8934}
8935#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8936
8937
8938#ifdef HAVE_DEVICE_MACROS
8939/*[clinic input]
8940os.major -> unsigned_int
8941
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008942 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008943 /
8944
8945Extracts a device major number from a raw device number.
8946[clinic start generated code]*/
8947
Larry Hastings2f936352014-08-05 14:04:04 +10008948static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008949os_major_impl(PyObject *module, dev_t device)
8950/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008951{
8952 return major(device);
8953}
8954
8955
8956/*[clinic input]
8957os.minor -> unsigned_int
8958
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008959 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008960 /
8961
8962Extracts a device minor number from a raw device number.
8963[clinic start generated code]*/
8964
Larry Hastings2f936352014-08-05 14:04:04 +10008965static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008966os_minor_impl(PyObject *module, dev_t device)
8967/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008968{
8969 return minor(device);
8970}
8971
8972
8973/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008974os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008975
8976 major: int
8977 minor: int
8978 /
8979
8980Composes a raw device number from the major and minor device numbers.
8981[clinic start generated code]*/
8982
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008983static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008984os_makedev_impl(PyObject *module, int major, int minor)
8985/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008986{
8987 return makedev(major, minor);
8988}
8989#endif /* HAVE_DEVICE_MACROS */
8990
8991
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008992#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008993/*[clinic input]
8994os.ftruncate
8995
8996 fd: int
8997 length: Py_off_t
8998 /
8999
9000Truncate a file, specified by file descriptor, to a specific length.
9001[clinic start generated code]*/
9002
Larry Hastings2f936352014-08-05 14:04:04 +10009003static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009004os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9005/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009006{
9007 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009008 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009009
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009010 do {
9011 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009012 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009013#ifdef MS_WINDOWS
9014 result = _chsize_s(fd, length);
9015#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009016 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009017#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009018 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009019 Py_END_ALLOW_THREADS
9020 } while (result != 0 && errno == EINTR &&
9021 !(async_err = PyErr_CheckSignals()));
9022 if (result != 0)
9023 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009024 Py_RETURN_NONE;
9025}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009026#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009027
9028
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009029#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009030/*[clinic input]
9031os.truncate
9032 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9033 length: Py_off_t
9034
9035Truncate a file, specified by path, to a specific length.
9036
9037On some platforms, path may also be specified as an open file descriptor.
9038 If this functionality is unavailable, using it raises an exception.
9039[clinic start generated code]*/
9040
Larry Hastings2f936352014-08-05 14:04:04 +10009041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009042os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9043/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009044{
9045 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009046#ifdef MS_WINDOWS
9047 int fd;
9048#endif
9049
9050 if (path->fd != -1)
9051 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009052
9053 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009054 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009055#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009056 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009057 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009058 result = -1;
9059 else {
9060 result = _chsize_s(fd, length);
9061 close(fd);
9062 if (result < 0)
9063 errno = result;
9064 }
9065#else
9066 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009067#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009068 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009069 Py_END_ALLOW_THREADS
9070 if (result < 0)
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07009071 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009072
9073 Py_RETURN_NONE;
9074}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009075#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009076
Ross Lagerwall7807c352011-03-17 20:20:30 +02009077
Victor Stinnerd6b17692014-09-30 12:20:05 +02009078/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9079 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9080 defined, which is the case in Python on AIX. AIX bug report:
9081 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9082#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9083# define POSIX_FADVISE_AIX_BUG
9084#endif
9085
Victor Stinnerec39e262014-09-30 12:35:58 +02009086
Victor Stinnerd6b17692014-09-30 12:20:05 +02009087#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009088/*[clinic input]
9089os.posix_fallocate
9090
9091 fd: int
9092 offset: Py_off_t
9093 length: Py_off_t
9094 /
9095
9096Ensure a file has allocated at least a particular number of bytes on disk.
9097
9098Ensure that the file specified by fd encompasses a range of bytes
9099starting at offset bytes from the beginning and continuing for length bytes.
9100[clinic start generated code]*/
9101
Larry Hastings2f936352014-08-05 14:04:04 +10009102static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009103os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009104 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009105/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009106{
9107 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009108 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009109
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009110 do {
9111 Py_BEGIN_ALLOW_THREADS
9112 result = posix_fallocate(fd, offset, length);
9113 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009114 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9115
9116 if (result == 0)
9117 Py_RETURN_NONE;
9118
9119 if (async_err)
9120 return NULL;
9121
9122 errno = result;
9123 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009124}
Victor Stinnerec39e262014-09-30 12:35:58 +02009125#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009126
Ross Lagerwall7807c352011-03-17 20:20:30 +02009127
Victor Stinnerd6b17692014-09-30 12:20:05 +02009128#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009129/*[clinic input]
9130os.posix_fadvise
9131
9132 fd: int
9133 offset: Py_off_t
9134 length: Py_off_t
9135 advice: int
9136 /
9137
9138Announce an intention to access data in a specific pattern.
9139
9140Announce an intention to access data in a specific pattern, thus allowing
9141the kernel to make optimizations.
9142The advice applies to the region of the file specified by fd starting at
9143offset and continuing for length bytes.
9144advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9145POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9146POSIX_FADV_DONTNEED.
9147[clinic start generated code]*/
9148
Larry Hastings2f936352014-08-05 14:04:04 +10009149static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009150os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009151 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009152/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009153{
9154 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009155 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009156
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009157 do {
9158 Py_BEGIN_ALLOW_THREADS
9159 result = posix_fadvise(fd, offset, length, advice);
9160 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009161 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9162
9163 if (result == 0)
9164 Py_RETURN_NONE;
9165
9166 if (async_err)
9167 return NULL;
9168
9169 errno = result;
9170 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009171}
Victor Stinnerec39e262014-09-30 12:35:58 +02009172#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009173
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009174#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009175
Fred Drake762e2061999-08-26 17:23:54 +00009176/* Save putenv() parameters as values here, so we can collect them when they
9177 * get re-set with another call for the same key. */
9178static PyObject *posix_putenv_garbage;
9179
Larry Hastings2f936352014-08-05 14:04:04 +10009180static void
9181posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009182{
Larry Hastings2f936352014-08-05 14:04:04 +10009183 /* Install the first arg and newstr in posix_putenv_garbage;
9184 * this will cause previous value to be collected. This has to
9185 * happen after the real putenv() call because the old value
9186 * was still accessible until then. */
9187 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9188 /* really not much we can do; just leak */
9189 PyErr_Clear();
9190 else
9191 Py_DECREF(value);
9192}
9193
9194
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009195#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009196/*[clinic input]
9197os.putenv
9198
9199 name: unicode
9200 value: unicode
9201 /
9202
9203Change or add an environment variable.
9204[clinic start generated code]*/
9205
Larry Hastings2f936352014-08-05 14:04:04 +10009206static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009207os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9208/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009209{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009210 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009211 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009212
Serhiy Storchaka77703942017-06-25 07:33:01 +03009213 /* Search from index 1 because on Windows starting '=' is allowed for
9214 defining hidden environment variables. */
9215 if (PyUnicode_GET_LENGTH(name) == 0 ||
9216 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9217 {
9218 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9219 return NULL;
9220 }
Larry Hastings2f936352014-08-05 14:04:04 +10009221 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9222 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009223 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009224 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009225
9226 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9227 if (env == NULL)
9228 goto error;
9229 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009230 PyErr_Format(PyExc_ValueError,
9231 "the environment variable is longer than %u characters",
9232 _MAX_ENV);
9233 goto error;
9234 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009235 if (wcslen(env) != (size_t)size) {
9236 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009237 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009238 }
9239
Larry Hastings2f936352014-08-05 14:04:04 +10009240 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009241 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009242 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009243 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009244
Larry Hastings2f936352014-08-05 14:04:04 +10009245 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009246 Py_RETURN_NONE;
9247
9248error:
Larry Hastings2f936352014-08-05 14:04:04 +10009249 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009250 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009251}
Larry Hastings2f936352014-08-05 14:04:04 +10009252#else /* MS_WINDOWS */
9253/*[clinic input]
9254os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009255
Larry Hastings2f936352014-08-05 14:04:04 +10009256 name: FSConverter
9257 value: FSConverter
9258 /
9259
9260Change or add an environment variable.
9261[clinic start generated code]*/
9262
Larry Hastings2f936352014-08-05 14:04:04 +10009263static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009264os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9265/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009266{
9267 PyObject *bytes = NULL;
9268 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009269 const char *name_string = PyBytes_AS_STRING(name);
9270 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009271
Serhiy Storchaka77703942017-06-25 07:33:01 +03009272 if (strchr(name_string, '=') != NULL) {
9273 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9274 return NULL;
9275 }
Larry Hastings2f936352014-08-05 14:04:04 +10009276 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9277 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009278 return NULL;
9279 }
9280
9281 env = PyBytes_AS_STRING(bytes);
9282 if (putenv(env)) {
9283 Py_DECREF(bytes);
9284 return posix_error();
9285 }
9286
9287 posix_putenv_garbage_setitem(name, bytes);
9288 Py_RETURN_NONE;
9289}
9290#endif /* MS_WINDOWS */
9291#endif /* HAVE_PUTENV */
9292
9293
9294#ifdef HAVE_UNSETENV
9295/*[clinic input]
9296os.unsetenv
9297 name: FSConverter
9298 /
9299
9300Delete an environment variable.
9301[clinic start generated code]*/
9302
Larry Hastings2f936352014-08-05 14:04:04 +10009303static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009304os_unsetenv_impl(PyObject *module, PyObject *name)
9305/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009306{
Victor Stinner984890f2011-11-24 13:53:38 +01009307#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009308 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009309#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009310
Victor Stinner984890f2011-11-24 13:53:38 +01009311#ifdef HAVE_BROKEN_UNSETENV
9312 unsetenv(PyBytes_AS_STRING(name));
9313#else
Victor Stinner65170952011-11-22 22:16:17 +01009314 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009315 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009316 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009317#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009318
Victor Stinner8c62be82010-05-06 00:08:46 +00009319 /* Remove the key from posix_putenv_garbage;
9320 * this will cause it to be collected. This has to
9321 * happen after the real unsetenv() call because the
9322 * old value was still accessible until then.
9323 */
Victor Stinner65170952011-11-22 22:16:17 +01009324 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009325 /* really not much we can do; just leak */
9326 PyErr_Clear();
9327 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009328 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009329}
Larry Hastings2f936352014-08-05 14:04:04 +10009330#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009331
Larry Hastings2f936352014-08-05 14:04:04 +10009332
9333/*[clinic input]
9334os.strerror
9335
9336 code: int
9337 /
9338
9339Translate an error code to a message string.
9340[clinic start generated code]*/
9341
Larry Hastings2f936352014-08-05 14:04:04 +10009342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009343os_strerror_impl(PyObject *module, int code)
9344/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009345{
9346 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 if (message == NULL) {
9348 PyErr_SetString(PyExc_ValueError,
9349 "strerror() argument out of range");
9350 return NULL;
9351 }
Victor Stinner1b579672011-12-17 05:47:23 +01009352 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009353}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009354
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009355
Guido van Rossumc9641791998-08-04 15:26:23 +00009356#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009357#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009358/*[clinic input]
9359os.WCOREDUMP -> bool
9360
9361 status: int
9362 /
9363
9364Return True if the process returning status was dumped to a core file.
9365[clinic start generated code]*/
9366
Larry Hastings2f936352014-08-05 14:04:04 +10009367static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009368os_WCOREDUMP_impl(PyObject *module, int status)
9369/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009370{
9371 WAIT_TYPE wait_status;
9372 WAIT_STATUS_INT(wait_status) = status;
9373 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009374}
9375#endif /* WCOREDUMP */
9376
Larry Hastings2f936352014-08-05 14:04:04 +10009377
Fred Drake106c1a02002-04-23 15:58:02 +00009378#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009379/*[clinic input]
9380os.WIFCONTINUED -> bool
9381
9382 status: int
9383
9384Return True if a particular process was continued from a job control stop.
9385
9386Return True if the process returning status was continued from a
9387job control stop.
9388[clinic start generated code]*/
9389
Larry Hastings2f936352014-08-05 14:04:04 +10009390static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009391os_WIFCONTINUED_impl(PyObject *module, int status)
9392/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009393{
9394 WAIT_TYPE wait_status;
9395 WAIT_STATUS_INT(wait_status) = status;
9396 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009397}
9398#endif /* WIFCONTINUED */
9399
Larry Hastings2f936352014-08-05 14:04:04 +10009400
Guido van Rossumc9641791998-08-04 15:26:23 +00009401#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009402/*[clinic input]
9403os.WIFSTOPPED -> bool
9404
9405 status: int
9406
9407Return True if the process returning status was stopped.
9408[clinic start generated code]*/
9409
Larry Hastings2f936352014-08-05 14:04:04 +10009410static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009411os_WIFSTOPPED_impl(PyObject *module, int status)
9412/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009413{
9414 WAIT_TYPE wait_status;
9415 WAIT_STATUS_INT(wait_status) = status;
9416 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009417}
9418#endif /* WIFSTOPPED */
9419
Larry Hastings2f936352014-08-05 14:04:04 +10009420
Guido van Rossumc9641791998-08-04 15:26:23 +00009421#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009422/*[clinic input]
9423os.WIFSIGNALED -> bool
9424
9425 status: int
9426
9427Return True if the process returning status was terminated by a signal.
9428[clinic start generated code]*/
9429
Larry Hastings2f936352014-08-05 14:04:04 +10009430static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009431os_WIFSIGNALED_impl(PyObject *module, int status)
9432/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009433{
9434 WAIT_TYPE wait_status;
9435 WAIT_STATUS_INT(wait_status) = status;
9436 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009437}
9438#endif /* WIFSIGNALED */
9439
Larry Hastings2f936352014-08-05 14:04:04 +10009440
Guido van Rossumc9641791998-08-04 15:26:23 +00009441#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009442/*[clinic input]
9443os.WIFEXITED -> bool
9444
9445 status: int
9446
9447Return True if the process returning status exited via the exit() system call.
9448[clinic start generated code]*/
9449
Larry Hastings2f936352014-08-05 14:04:04 +10009450static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009451os_WIFEXITED_impl(PyObject *module, int status)
9452/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009453{
9454 WAIT_TYPE wait_status;
9455 WAIT_STATUS_INT(wait_status) = status;
9456 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009457}
9458#endif /* WIFEXITED */
9459
Larry Hastings2f936352014-08-05 14:04:04 +10009460
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009461#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009462/*[clinic input]
9463os.WEXITSTATUS -> int
9464
9465 status: int
9466
9467Return the process return code from status.
9468[clinic start generated code]*/
9469
Larry Hastings2f936352014-08-05 14:04:04 +10009470static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009471os_WEXITSTATUS_impl(PyObject *module, int status)
9472/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009473{
9474 WAIT_TYPE wait_status;
9475 WAIT_STATUS_INT(wait_status) = status;
9476 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009477}
9478#endif /* WEXITSTATUS */
9479
Larry Hastings2f936352014-08-05 14:04:04 +10009480
Guido van Rossumc9641791998-08-04 15:26:23 +00009481#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009482/*[clinic input]
9483os.WTERMSIG -> int
9484
9485 status: int
9486
9487Return the signal that terminated the process that provided the status value.
9488[clinic start generated code]*/
9489
Larry Hastings2f936352014-08-05 14:04:04 +10009490static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009491os_WTERMSIG_impl(PyObject *module, int status)
9492/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009493{
9494 WAIT_TYPE wait_status;
9495 WAIT_STATUS_INT(wait_status) = status;
9496 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009497}
9498#endif /* WTERMSIG */
9499
Larry Hastings2f936352014-08-05 14:04:04 +10009500
Guido van Rossumc9641791998-08-04 15:26:23 +00009501#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009502/*[clinic input]
9503os.WSTOPSIG -> int
9504
9505 status: int
9506
9507Return the signal that stopped the process that provided the status value.
9508[clinic start generated code]*/
9509
Larry Hastings2f936352014-08-05 14:04:04 +10009510static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009511os_WSTOPSIG_impl(PyObject *module, int status)
9512/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009513{
9514 WAIT_TYPE wait_status;
9515 WAIT_STATUS_INT(wait_status) = status;
9516 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009517}
9518#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009519#endif /* HAVE_SYS_WAIT_H */
9520
9521
Thomas Wouters477c8d52006-05-27 19:21:47 +00009522#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009523#ifdef _SCO_DS
9524/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9525 needed definitions in sys/statvfs.h */
9526#define _SVID3
9527#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009528#include <sys/statvfs.h>
9529
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009530static PyObject*
9531_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9533 if (v == NULL)
9534 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009535
9536#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9538 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9539 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9540 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9541 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9542 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9543 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9544 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9545 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9546 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009547#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9549 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9550 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009551 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009553 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009555 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009557 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009559 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009561 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9563 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009564#endif
Michael Felt502d5512018-01-05 13:01:58 +01009565/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9566 * (issue #32390). */
9567#if defined(_AIX) && defined(_ALL_SOURCE)
9568 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9569#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009570 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009571#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009572 if (PyErr_Occurred()) {
9573 Py_DECREF(v);
9574 return NULL;
9575 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009576
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009578}
9579
Larry Hastings2f936352014-08-05 14:04:04 +10009580
9581/*[clinic input]
9582os.fstatvfs
9583 fd: int
9584 /
9585
9586Perform an fstatvfs system call on the given fd.
9587
9588Equivalent to statvfs(fd).
9589[clinic start generated code]*/
9590
Larry Hastings2f936352014-08-05 14:04:04 +10009591static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009592os_fstatvfs_impl(PyObject *module, int fd)
9593/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009594{
9595 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009596 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009598
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009599 do {
9600 Py_BEGIN_ALLOW_THREADS
9601 result = fstatvfs(fd, &st);
9602 Py_END_ALLOW_THREADS
9603 } while (result != 0 && errno == EINTR &&
9604 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009605 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009606 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009607
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009609}
Larry Hastings2f936352014-08-05 14:04:04 +10009610#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009611
9612
Thomas Wouters477c8d52006-05-27 19:21:47 +00009613#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009614#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009615/*[clinic input]
9616os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009617
Larry Hastings2f936352014-08-05 14:04:04 +10009618 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9619
9620Perform a statvfs system call on the given path.
9621
9622path may always be specified as a string.
9623On some platforms, path may also be specified as an open file descriptor.
9624 If this functionality is unavailable, using it raises an exception.
9625[clinic start generated code]*/
9626
Larry Hastings2f936352014-08-05 14:04:04 +10009627static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009628os_statvfs_impl(PyObject *module, path_t *path)
9629/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009630{
9631 int result;
9632 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009633
9634 Py_BEGIN_ALLOW_THREADS
9635#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009636 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009637#ifdef __APPLE__
9638 /* handle weak-linking on Mac OS X 10.3 */
9639 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009640 fd_specified("statvfs", path->fd);
9641 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009642 }
9643#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009644 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009645 }
9646 else
9647#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009648 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009649 Py_END_ALLOW_THREADS
9650
9651 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009652 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009653 }
9654
Larry Hastings2f936352014-08-05 14:04:04 +10009655 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009656}
Larry Hastings2f936352014-08-05 14:04:04 +10009657#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9658
Guido van Rossum94f6f721999-01-06 18:42:14 +00009659
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009660#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009661/*[clinic input]
9662os._getdiskusage
9663
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009664 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10009665
9666Return disk usage statistics about the given path as a (total, free) tuple.
9667[clinic start generated code]*/
9668
Larry Hastings2f936352014-08-05 14:04:04 +10009669static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009670os__getdiskusage_impl(PyObject *module, path_t *path)
9671/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009672{
9673 BOOL retval;
9674 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009675
9676 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009677 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009678 Py_END_ALLOW_THREADS
9679 if (retval == 0)
9680 return PyErr_SetFromWindowsErr(0);
9681
9682 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9683}
Larry Hastings2f936352014-08-05 14:04:04 +10009684#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009685
9686
Fred Drakec9680921999-12-13 16:37:25 +00009687/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9688 * It maps strings representing configuration variable names to
9689 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009690 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009691 * rarely-used constants. There are three separate tables that use
9692 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009693 *
9694 * This code is always included, even if none of the interfaces that
9695 * need it are included. The #if hackery needed to avoid it would be
9696 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009697 */
9698struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009699 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009700 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009701};
9702
Fred Drake12c6e2d1999-12-14 21:25:03 +00009703static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009704conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009705 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009706{
Christian Heimes217cfd12007-12-02 14:31:20 +00009707 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009708 int value = _PyLong_AsInt(arg);
9709 if (value == -1 && PyErr_Occurred())
9710 return 0;
9711 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009712 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009713 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009714 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009715 /* look up the value in the table using a binary search */
9716 size_t lo = 0;
9717 size_t mid;
9718 size_t hi = tablesize;
9719 int cmp;
9720 const char *confname;
9721 if (!PyUnicode_Check(arg)) {
9722 PyErr_SetString(PyExc_TypeError,
9723 "configuration names must be strings or integers");
9724 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009726 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009727 if (confname == NULL)
9728 return 0;
9729 while (lo < hi) {
9730 mid = (lo + hi) / 2;
9731 cmp = strcmp(confname, table[mid].name);
9732 if (cmp < 0)
9733 hi = mid;
9734 else if (cmp > 0)
9735 lo = mid + 1;
9736 else {
9737 *valuep = table[mid].value;
9738 return 1;
9739 }
9740 }
9741 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9742 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009744}
9745
9746
9747#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9748static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009749#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009751#endif
9752#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009754#endif
Fred Drakec9680921999-12-13 16:37:25 +00009755#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009800#ifdef _PC_ACL_ENABLED
9801 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9802#endif
9803#ifdef _PC_MIN_HOLE_SIZE
9804 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9805#endif
9806#ifdef _PC_ALLOC_SIZE_MIN
9807 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9808#endif
9809#ifdef _PC_REC_INCR_XFER_SIZE
9810 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9811#endif
9812#ifdef _PC_REC_MAX_XFER_SIZE
9813 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9814#endif
9815#ifdef _PC_REC_MIN_XFER_SIZE
9816 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9817#endif
9818#ifdef _PC_REC_XFER_ALIGN
9819 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9820#endif
9821#ifdef _PC_SYMLINK_MAX
9822 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9823#endif
9824#ifdef _PC_XATTR_ENABLED
9825 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9826#endif
9827#ifdef _PC_XATTR_EXISTS
9828 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9829#endif
9830#ifdef _PC_TIMESTAMP_RESOLUTION
9831 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9832#endif
Fred Drakec9680921999-12-13 16:37:25 +00009833};
9834
Fred Drakec9680921999-12-13 16:37:25 +00009835static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009836conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009837{
9838 return conv_confname(arg, valuep, posix_constants_pathconf,
9839 sizeof(posix_constants_pathconf)
9840 / sizeof(struct constdef));
9841}
9842#endif
9843
Larry Hastings2f936352014-08-05 14:04:04 +10009844
Fred Drakec9680921999-12-13 16:37:25 +00009845#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009846/*[clinic input]
9847os.fpathconf -> long
9848
9849 fd: int
9850 name: path_confname
9851 /
9852
9853Return the configuration limit name for the file descriptor fd.
9854
9855If there is no limit, return -1.
9856[clinic start generated code]*/
9857
Larry Hastings2f936352014-08-05 14:04:04 +10009858static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009859os_fpathconf_impl(PyObject *module, int fd, int name)
9860/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009861{
9862 long limit;
9863
9864 errno = 0;
9865 limit = fpathconf(fd, name);
9866 if (limit == -1 && errno != 0)
9867 posix_error();
9868
9869 return limit;
9870}
9871#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009872
9873
9874#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009875/*[clinic input]
9876os.pathconf -> long
9877 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9878 name: path_confname
9879
9880Return the configuration limit name for the file or directory path.
9881
9882If there is no limit, return -1.
9883On some platforms, path may also be specified as an open file descriptor.
9884 If this functionality is unavailable, using it raises an exception.
9885[clinic start generated code]*/
9886
Larry Hastings2f936352014-08-05 14:04:04 +10009887static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009888os_pathconf_impl(PyObject *module, path_t *path, int name)
9889/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009890{
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009892
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009894#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009895 if (path->fd != -1)
9896 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009897 else
9898#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009899 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 if (limit == -1 && errno != 0) {
9901 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009902 /* could be a path or name problem */
9903 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009904 else
Larry Hastings2f936352014-08-05 14:04:04 +10009905 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 }
Larry Hastings2f936352014-08-05 14:04:04 +10009907
9908 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009909}
Larry Hastings2f936352014-08-05 14:04:04 +10009910#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009911
9912#ifdef HAVE_CONFSTR
9913static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009914#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009916#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009917#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009919#endif
9920#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009922#endif
Fred Draked86ed291999-12-15 15:34:33 +00009923#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009925#endif
9926#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009928#endif
9929#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009931#endif
9932#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009934#endif
Fred Drakec9680921999-12-13 16:37:25 +00009935#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
Fred Draked86ed291999-12-15 15:34:33 +00009959#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009961#endif
Fred Drakec9680921999-12-13 16:37:25 +00009962#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
Fred Draked86ed291999-12-15 15:34:33 +00009965#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009967#endif
9968#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009970#endif
9971#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009973#endif
9974#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009976#endif
Fred Drakec9680921999-12-13 16:37:25 +00009977#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
Fred Draked86ed291999-12-15 15:34:33 +000010025#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010027#endif
10028#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010030#endif
10031#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010033#endif
10034#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010036#endif
10037#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010039#endif
10040#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010042#endif
10043#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010045#endif
10046#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010048#endif
10049#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010051#endif
10052#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010054#endif
10055#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010057#endif
10058#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010060#endif
10061#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010063#endif
Fred Drakec9680921999-12-13 16:37:25 +000010064};
10065
10066static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010067conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010068{
10069 return conv_confname(arg, valuep, posix_constants_confstr,
10070 sizeof(posix_constants_confstr)
10071 / sizeof(struct constdef));
10072}
10073
Larry Hastings2f936352014-08-05 14:04:04 +100010074
10075/*[clinic input]
10076os.confstr
10077
10078 name: confstr_confname
10079 /
10080
10081Return a string-valued system configuration variable.
10082[clinic start generated code]*/
10083
Larry Hastings2f936352014-08-05 14:04:04 +100010084static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010085os_confstr_impl(PyObject *module, int name)
10086/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010087{
10088 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010089 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010090 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010091
Victor Stinnercb043522010-09-10 23:49:04 +000010092 errno = 0;
10093 len = confstr(name, buffer, sizeof(buffer));
10094 if (len == 0) {
10095 if (errno) {
10096 posix_error();
10097 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010098 }
10099 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010100 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010101 }
10102 }
Victor Stinnercb043522010-09-10 23:49:04 +000010103
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010104 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010105 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010106 char *buf = PyMem_Malloc(len);
10107 if (buf == NULL)
10108 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010109 len2 = confstr(name, buf, len);
10110 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010111 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010112 PyMem_Free(buf);
10113 }
10114 else
10115 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010116 return result;
10117}
Larry Hastings2f936352014-08-05 14:04:04 +100010118#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010119
10120
10121#ifdef HAVE_SYSCONF
10122static struct constdef posix_constants_sysconf[] = {
10123#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
Fred Draked86ed291999-12-15 15:34:33 +000010153#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010155#endif
10156#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010158#endif
Fred Drakec9680921999-12-13 16:37:25 +000010159#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
Fred Drakec9680921999-12-13 16:37:25 +000010162#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
Fred Draked86ed291999-12-15 15:34:33 +000010177#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010179#endif
Fred Drakec9680921999-12-13 16:37:25 +000010180#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
Fred Draked86ed291999-12-15 15:34:33 +000010195#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010197#endif
Fred Drakec9680921999-12-13 16:37:25 +000010198#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
Fred Draked86ed291999-12-15 15:34:33 +000010267#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010269#endif
Fred Drakec9680921999-12-13 16:37:25 +000010270#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
Fred Draked86ed291999-12-15 15:34:33 +000010279#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010281#endif
Fred Drakec9680921999-12-13 16:37:25 +000010282#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
Fred Draked86ed291999-12-15 15:34:33 +000010285#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010287#endif
10288#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010290#endif
Fred Drakec9680921999-12-13 16:37:25 +000010291#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
10294#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
Fred Draked86ed291999-12-15 15:34:33 +000010303#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010305#endif
Fred Drakec9680921999-12-13 16:37:25 +000010306#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
Fred Draked86ed291999-12-15 15:34:33 +000010327#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010329#endif
Fred Drakec9680921999-12-13 16:37:25 +000010330#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
Fred Draked86ed291999-12-15 15:34:33 +000010336#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010338#endif
Fred Drakec9680921999-12-13 16:37:25 +000010339#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010353#endif
10354#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010356#endif
10357#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010359#endif
10360#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010362#endif
10363#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010365#endif
Fred Draked86ed291999-12-15 15:34:33 +000010366#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010368#endif
10369#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010371#endif
Fred Drakec9680921999-12-13 16:37:25 +000010372#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010374#endif
10375#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010377#endif
10378#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010380#endif
10381#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010383#endif
10384#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010386#endif
10387#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010389#endif
10390#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010392#endif
10393#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010395#endif
10396#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010398#endif
10399#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010401#endif
10402#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010404#endif
10405#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010407#endif
10408#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010410#endif
10411#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010413#endif
10414#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010416#endif
10417#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010419#endif
10420#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010421 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010422#endif
10423#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010425#endif
10426#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010427 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010428#endif
10429#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010430 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010431#endif
10432#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010434#endif
10435#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010437#endif
10438#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010440#endif
10441#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010443#endif
10444#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010445 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010446#endif
10447#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010449#endif
10450#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010452#endif
10453#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010455#endif
10456#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010458#endif
10459#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010461#endif
10462#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010464#endif
10465#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010467#endif
10468#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010470#endif
10471#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010473#endif
10474#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010476#endif
Fred Draked86ed291999-12-15 15:34:33 +000010477#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010479#endif
Fred Drakec9680921999-12-13 16:37:25 +000010480#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010482#endif
10483#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010485#endif
10486#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010488#endif
10489#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010491#endif
10492#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010494#endif
10495#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010496 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010497#endif
10498#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010500#endif
10501#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010503#endif
10504#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010506#endif
10507#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010509#endif
10510#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010512#endif
10513#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010515#endif
10516#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010517 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010518#endif
10519#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010521#endif
10522#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010524#endif
10525#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010527#endif
10528#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010530#endif
10531#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010533#endif
10534#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010536#endif
10537#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010539#endif
10540#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010542#endif
10543#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010545#endif
10546#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010548#endif
10549#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010551#endif
10552#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010554#endif
10555#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010557#endif
10558#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010560#endif
10561#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010563#endif
10564#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010566#endif
10567#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010569#endif
10570#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010572#endif
10573#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010575#endif
10576#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010578#endif
10579#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010581#endif
10582#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010584#endif
10585#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010587#endif
10588#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010589 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010590#endif
10591#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010593#endif
10594#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010596#endif
10597#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010599#endif
10600#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010602#endif
10603#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010605#endif
10606#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010608#endif
10609#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010610 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010611#endif
10612#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010614#endif
10615};
10616
10617static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010618conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010619{
10620 return conv_confname(arg, valuep, posix_constants_sysconf,
10621 sizeof(posix_constants_sysconf)
10622 / sizeof(struct constdef));
10623}
10624
Larry Hastings2f936352014-08-05 14:04:04 +100010625
10626/*[clinic input]
10627os.sysconf -> long
10628 name: sysconf_confname
10629 /
10630
10631Return an integer-valued system configuration variable.
10632[clinic start generated code]*/
10633
Larry Hastings2f936352014-08-05 14:04:04 +100010634static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010635os_sysconf_impl(PyObject *module, int name)
10636/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010637{
10638 long value;
10639
10640 errno = 0;
10641 value = sysconf(name);
10642 if (value == -1 && errno != 0)
10643 posix_error();
10644 return value;
10645}
10646#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010647
10648
Fred Drakebec628d1999-12-15 18:31:10 +000010649/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010650 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010651 * the exported dictionaries that are used to publish information about the
10652 * names available on the host platform.
10653 *
10654 * Sorting the table at runtime ensures that the table is properly ordered
10655 * when used, even for platforms we're not able to test on. It also makes
10656 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010657 */
Fred Drakebec628d1999-12-15 18:31:10 +000010658
10659static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010660cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010661{
10662 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010664 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010665 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010666
10667 return strcmp(c1->name, c2->name);
10668}
10669
10670static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010671setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010672 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010673{
Fred Drakebec628d1999-12-15 18:31:10 +000010674 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010675 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010676
10677 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10678 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010679 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010680 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010681
Barry Warsaw3155db32000-04-13 15:20:40 +000010682 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010683 PyObject *o = PyLong_FromLong(table[i].value);
10684 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10685 Py_XDECREF(o);
10686 Py_DECREF(d);
10687 return -1;
10688 }
10689 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010690 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010691 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010692}
10693
Fred Drakebec628d1999-12-15 18:31:10 +000010694/* Return -1 on failure, 0 on success. */
10695static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010696setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010697{
10698#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010699 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010700 sizeof(posix_constants_pathconf)
10701 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010702 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010703 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010704#endif
10705#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010706 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010707 sizeof(posix_constants_confstr)
10708 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010709 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010710 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010711#endif
10712#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010713 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010714 sizeof(posix_constants_sysconf)
10715 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010716 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010717 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010718#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010719 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010720}
Fred Draked86ed291999-12-15 15:34:33 +000010721
10722
Larry Hastings2f936352014-08-05 14:04:04 +100010723/*[clinic input]
10724os.abort
10725
10726Abort the interpreter immediately.
10727
10728This function 'dumps core' or otherwise fails in the hardest way possible
10729on the hosting operating system. This function never returns.
10730[clinic start generated code]*/
10731
Larry Hastings2f936352014-08-05 14:04:04 +100010732static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010733os_abort_impl(PyObject *module)
10734/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010735{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010736 abort();
10737 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010738#ifndef __clang__
10739 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10740 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10741 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010742 Py_FatalError("abort() called from Python code didn't abort!");
10743 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010744#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010745}
Fred Drakebec628d1999-12-15 18:31:10 +000010746
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010747#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010748/* Grab ShellExecute dynamically from shell32 */
10749static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010750static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10751 LPCWSTR, INT);
10752static int
10753check_ShellExecute()
10754{
10755 HINSTANCE hShell32;
10756
10757 /* only recheck */
10758 if (-1 == has_ShellExecute) {
10759 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010760 /* Security note: this call is not vulnerable to "DLL hijacking".
10761 SHELL32 is part of "KnownDLLs" and so Windows always load
10762 the system SHELL32.DLL, even if there is another SHELL32.DLL
10763 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010764 hShell32 = LoadLibraryW(L"SHELL32");
10765 Py_END_ALLOW_THREADS
10766 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010767 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10768 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010769 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010770 } else {
10771 has_ShellExecute = 0;
10772 }
10773 }
10774 return has_ShellExecute;
10775}
10776
10777
Steve Dowercc16be82016-09-08 10:35:16 -070010778/*[clinic input]
10779os.startfile
10780 filepath: path_t
10781 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010782
Steve Dowercc16be82016-09-08 10:35:16 -070010783startfile(filepath [, operation])
10784
10785Start a file with its associated application.
10786
10787When "operation" is not specified or "open", this acts like
10788double-clicking the file in Explorer, or giving the file name as an
10789argument to the DOS "start" command: the file is opened with whatever
10790application (if any) its extension is associated.
10791When another "operation" is given, it specifies what should be done with
10792the file. A typical operation is "print".
10793
10794startfile returns as soon as the associated application is launched.
10795There is no option to wait for the application to close, and no way
10796to retrieve the application's exit status.
10797
10798The filepath is relative to the current directory. If you want to use
10799an absolute path, make sure the first character is not a slash ("/");
10800the underlying Win32 ShellExecute function doesn't work if it is.
10801[clinic start generated code]*/
10802
10803static PyObject *
10804os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10805/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10806{
10807 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010808
10809 if(!check_ShellExecute()) {
10810 /* If the OS doesn't have ShellExecute, return a
10811 NotImplementedError. */
10812 return PyErr_Format(PyExc_NotImplementedError,
10813 "startfile not available on this platform");
10814 }
10815
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010817 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010818 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010819 Py_END_ALLOW_THREADS
10820
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010822 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010823 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 }
Steve Dowercc16be82016-09-08 10:35:16 -070010825 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010826}
Larry Hastings2f936352014-08-05 14:04:04 +100010827#endif /* MS_WINDOWS */
10828
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010829
Martin v. Löwis438b5342002-12-27 10:16:42 +000010830#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010831/*[clinic input]
10832os.getloadavg
10833
10834Return average recent system load information.
10835
10836Return the number of processes in the system run queue averaged over
10837the last 1, 5, and 15 minutes as a tuple of three floats.
10838Raises OSError if the load average was unobtainable.
10839[clinic start generated code]*/
10840
Larry Hastings2f936352014-08-05 14:04:04 +100010841static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010842os_getloadavg_impl(PyObject *module)
10843/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010844{
10845 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010846 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010847 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10848 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010849 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010850 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010851}
Larry Hastings2f936352014-08-05 14:04:04 +100010852#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010853
Larry Hastings2f936352014-08-05 14:04:04 +100010854
10855/*[clinic input]
10856os.device_encoding
10857 fd: int
10858
10859Return a string describing the encoding of a terminal's file descriptor.
10860
10861The file descriptor must be attached to a terminal.
10862If the device is not a terminal, return None.
10863[clinic start generated code]*/
10864
Larry Hastings2f936352014-08-05 14:04:04 +100010865static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010866os_device_encoding_impl(PyObject *module, int fd)
10867/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010868{
Brett Cannonefb00c02012-02-29 18:31:31 -050010869 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010870}
10871
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010872
Larry Hastings2f936352014-08-05 14:04:04 +100010873#ifdef HAVE_SETRESUID
10874/*[clinic input]
10875os.setresuid
10876
10877 ruid: uid_t
10878 euid: uid_t
10879 suid: uid_t
10880 /
10881
10882Set the current process's real, effective, and saved user ids.
10883[clinic start generated code]*/
10884
Larry Hastings2f936352014-08-05 14:04:04 +100010885static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010886os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10887/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010888{
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 if (setresuid(ruid, euid, suid) < 0)
10890 return posix_error();
10891 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010892}
Larry Hastings2f936352014-08-05 14:04:04 +100010893#endif /* HAVE_SETRESUID */
10894
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010895
10896#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010897/*[clinic input]
10898os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010899
Larry Hastings2f936352014-08-05 14:04:04 +100010900 rgid: gid_t
10901 egid: gid_t
10902 sgid: gid_t
10903 /
10904
10905Set the current process's real, effective, and saved group ids.
10906[clinic start generated code]*/
10907
Larry Hastings2f936352014-08-05 14:04:04 +100010908static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010909os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10910/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010911{
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 if (setresgid(rgid, egid, sgid) < 0)
10913 return posix_error();
10914 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010915}
Larry Hastings2f936352014-08-05 14:04:04 +100010916#endif /* HAVE_SETRESGID */
10917
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010918
10919#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010920/*[clinic input]
10921os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010922
Larry Hastings2f936352014-08-05 14:04:04 +100010923Return a tuple of the current process's real, effective, and saved user ids.
10924[clinic start generated code]*/
10925
Larry Hastings2f936352014-08-05 14:04:04 +100010926static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010927os_getresuid_impl(PyObject *module)
10928/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010929{
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010931 if (getresuid(&ruid, &euid, &suid) < 0)
10932 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010933 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10934 _PyLong_FromUid(euid),
10935 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010936}
Larry Hastings2f936352014-08-05 14:04:04 +100010937#endif /* HAVE_GETRESUID */
10938
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010939
10940#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010941/*[clinic input]
10942os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010943
Larry Hastings2f936352014-08-05 14:04:04 +100010944Return a tuple of the current process's real, effective, and saved group ids.
10945[clinic start generated code]*/
10946
Larry Hastings2f936352014-08-05 14:04:04 +100010947static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010948os_getresgid_impl(PyObject *module)
10949/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010950{
10951 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010952 if (getresgid(&rgid, &egid, &sgid) < 0)
10953 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010954 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10955 _PyLong_FromGid(egid),
10956 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010957}
Larry Hastings2f936352014-08-05 14:04:04 +100010958#endif /* HAVE_GETRESGID */
10959
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010960
Benjamin Peterson9428d532011-09-14 11:45:52 -040010961#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010962/*[clinic input]
10963os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010964
Larry Hastings2f936352014-08-05 14:04:04 +100010965 path: path_t(allow_fd=True)
10966 attribute: path_t
10967 *
10968 follow_symlinks: bool = True
10969
10970Return the value of extended attribute attribute on path.
10971
BNMetrics08026b12018-11-02 17:56:25 +000010972path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100010973If follow_symlinks is False, and the last element of the path is a symbolic
10974 link, getxattr will examine the symbolic link itself instead of the file
10975 the link points to.
10976
10977[clinic start generated code]*/
10978
Larry Hastings2f936352014-08-05 14:04:04 +100010979static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010980os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010981 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000010982/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010983{
10984 Py_ssize_t i;
10985 PyObject *buffer = NULL;
10986
10987 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10988 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010989
Larry Hastings9cf065c2012-06-22 16:30:09 -070010990 for (i = 0; ; i++) {
10991 void *ptr;
10992 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010993 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010994 Py_ssize_t buffer_size = buffer_sizes[i];
10995 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010996 path_error(path);
10997 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010998 }
10999 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11000 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011001 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011002 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011003
Larry Hastings9cf065c2012-06-22 16:30:09 -070011004 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011005 if (path->fd >= 0)
11006 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011007 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011008 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011009 else
Larry Hastings2f936352014-08-05 14:04:04 +100011010 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011012
Larry Hastings9cf065c2012-06-22 16:30:09 -070011013 if (result < 0) {
11014 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011015 if (errno == ERANGE)
11016 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011017 path_error(path);
11018 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011019 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011020
Larry Hastings9cf065c2012-06-22 16:30:09 -070011021 if (result != buffer_size) {
11022 /* Can only shrink. */
11023 _PyBytes_Resize(&buffer, result);
11024 }
11025 break;
11026 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011027
Larry Hastings9cf065c2012-06-22 16:30:09 -070011028 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011029}
11030
Larry Hastings2f936352014-08-05 14:04:04 +100011031
11032/*[clinic input]
11033os.setxattr
11034
11035 path: path_t(allow_fd=True)
11036 attribute: path_t
11037 value: Py_buffer
11038 flags: int = 0
11039 *
11040 follow_symlinks: bool = True
11041
11042Set extended attribute attribute on path to value.
11043
BNMetrics08026b12018-11-02 17:56:25 +000011044path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011045If follow_symlinks is False, and the last element of the path is a symbolic
11046 link, setxattr will modify the symbolic link itself instead of the file
11047 the link points to.
11048
11049[clinic start generated code]*/
11050
Benjamin Peterson799bd802011-08-31 22:15:17 -040011051static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011052os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011053 Py_buffer *value, int flags, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011054/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011055{
Larry Hastings2f936352014-08-05 14:04:04 +100011056 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011057
Larry Hastings2f936352014-08-05 14:04:04 +100011058 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011059 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011060
Benjamin Peterson799bd802011-08-31 22:15:17 -040011061 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011062 if (path->fd > -1)
11063 result = fsetxattr(path->fd, attribute->narrow,
11064 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011065 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011066 result = setxattr(path->narrow, attribute->narrow,
11067 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011068 else
Larry Hastings2f936352014-08-05 14:04:04 +100011069 result = lsetxattr(path->narrow, attribute->narrow,
11070 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011071 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011072
Larry Hastings9cf065c2012-06-22 16:30:09 -070011073 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011074 path_error(path);
11075 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011076 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011077
Larry Hastings2f936352014-08-05 14:04:04 +100011078 Py_RETURN_NONE;
11079}
11080
11081
11082/*[clinic input]
11083os.removexattr
11084
11085 path: path_t(allow_fd=True)
11086 attribute: path_t
11087 *
11088 follow_symlinks: bool = True
11089
11090Remove extended attribute attribute on path.
11091
BNMetrics08026b12018-11-02 17:56:25 +000011092path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011093If follow_symlinks is False, and the last element of the path is a symbolic
11094 link, removexattr will modify the symbolic link itself instead of the file
11095 the link points to.
11096
11097[clinic start generated code]*/
11098
Larry Hastings2f936352014-08-05 14:04:04 +100011099static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011100os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011101 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011102/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011103{
11104 ssize_t result;
11105
11106 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11107 return NULL;
11108
11109 Py_BEGIN_ALLOW_THREADS;
11110 if (path->fd > -1)
11111 result = fremovexattr(path->fd, attribute->narrow);
11112 else if (follow_symlinks)
11113 result = removexattr(path->narrow, attribute->narrow);
11114 else
11115 result = lremovexattr(path->narrow, attribute->narrow);
11116 Py_END_ALLOW_THREADS;
11117
11118 if (result) {
11119 return path_error(path);
11120 }
11121
11122 Py_RETURN_NONE;
11123}
11124
11125
11126/*[clinic input]
11127os.listxattr
11128
11129 path: path_t(allow_fd=True, nullable=True) = None
11130 *
11131 follow_symlinks: bool = True
11132
11133Return a list of extended attributes on path.
11134
BNMetrics08026b12018-11-02 17:56:25 +000011135path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011136if path is None, listxattr will examine the current directory.
11137If follow_symlinks is False, and the last element of the path is a symbolic
11138 link, listxattr will examine the symbolic link itself instead of the file
11139 the link points to.
11140[clinic start generated code]*/
11141
Larry Hastings2f936352014-08-05 14:04:04 +100011142static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011143os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011144/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011145{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011146 Py_ssize_t i;
11147 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011148 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011149 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011150
Larry Hastings2f936352014-08-05 14:04:04 +100011151 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011152 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011153
Larry Hastings2f936352014-08-05 14:04:04 +100011154 name = path->narrow ? path->narrow : ".";
11155
Larry Hastings9cf065c2012-06-22 16:30:09 -070011156 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011157 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011158 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011159 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011160 Py_ssize_t buffer_size = buffer_sizes[i];
11161 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011162 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011163 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011164 break;
11165 }
11166 buffer = PyMem_MALLOC(buffer_size);
11167 if (!buffer) {
11168 PyErr_NoMemory();
11169 break;
11170 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011171
Larry Hastings9cf065c2012-06-22 16:30:09 -070011172 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011173 if (path->fd > -1)
11174 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011175 else if (follow_symlinks)
11176 length = listxattr(name, buffer, buffer_size);
11177 else
11178 length = llistxattr(name, buffer, buffer_size);
11179 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011180
Larry Hastings9cf065c2012-06-22 16:30:09 -070011181 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011182 if (errno == ERANGE) {
11183 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011184 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011185 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011186 }
Larry Hastings2f936352014-08-05 14:04:04 +100011187 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011188 break;
11189 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011190
Larry Hastings9cf065c2012-06-22 16:30:09 -070011191 result = PyList_New(0);
11192 if (!result) {
11193 goto exit;
11194 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011195
Larry Hastings9cf065c2012-06-22 16:30:09 -070011196 end = buffer + length;
11197 for (trace = start = buffer; trace != end; trace++) {
11198 if (!*trace) {
11199 int error;
11200 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11201 trace - start);
11202 if (!attribute) {
11203 Py_DECREF(result);
11204 result = NULL;
11205 goto exit;
11206 }
11207 error = PyList_Append(result, attribute);
11208 Py_DECREF(attribute);
11209 if (error) {
11210 Py_DECREF(result);
11211 result = NULL;
11212 goto exit;
11213 }
11214 start = trace + 1;
11215 }
11216 }
11217 break;
11218 }
11219exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011220 if (buffer)
11221 PyMem_FREE(buffer);
11222 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011223}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011224#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011225
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011226
Larry Hastings2f936352014-08-05 14:04:04 +100011227/*[clinic input]
11228os.urandom
11229
11230 size: Py_ssize_t
11231 /
11232
11233Return a bytes object containing random bytes suitable for cryptographic use.
11234[clinic start generated code]*/
11235
Larry Hastings2f936352014-08-05 14:04:04 +100011236static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011237os_urandom_impl(PyObject *module, Py_ssize_t size)
11238/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011239{
11240 PyObject *bytes;
11241 int result;
11242
Georg Brandl2fb477c2012-02-21 00:33:36 +010011243 if (size < 0)
11244 return PyErr_Format(PyExc_ValueError,
11245 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011246 bytes = PyBytes_FromStringAndSize(NULL, size);
11247 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011248 return NULL;
11249
Victor Stinnere66987e2016-09-06 16:33:52 -070011250 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011251 if (result == -1) {
11252 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011253 return NULL;
11254 }
Larry Hastings2f936352014-08-05 14:04:04 +100011255 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011256}
11257
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011258/* Terminal size querying */
11259
11260static PyTypeObject TerminalSizeType;
11261
11262PyDoc_STRVAR(TerminalSize_docstring,
11263 "A tuple of (columns, lines) for holding terminal window size");
11264
11265static PyStructSequence_Field TerminalSize_fields[] = {
11266 {"columns", "width of the terminal window in characters"},
11267 {"lines", "height of the terminal window in characters"},
11268 {NULL, NULL}
11269};
11270
11271static PyStructSequence_Desc TerminalSize_desc = {
11272 "os.terminal_size",
11273 TerminalSize_docstring,
11274 TerminalSize_fields,
11275 2,
11276};
11277
11278#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011279/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011280PyDoc_STRVAR(termsize__doc__,
11281 "Return the size of the terminal window as (columns, lines).\n" \
11282 "\n" \
11283 "The optional argument fd (default standard output) specifies\n" \
11284 "which file descriptor should be queried.\n" \
11285 "\n" \
11286 "If the file descriptor is not connected to a terminal, an OSError\n" \
11287 "is thrown.\n" \
11288 "\n" \
11289 "This function will only be defined if an implementation is\n" \
11290 "available for this system.\n" \
11291 "\n" \
11292 "shutil.get_terminal_size is the high-level function which should \n" \
11293 "normally be used, os.get_terminal_size is the low-level implementation.");
11294
11295static PyObject*
11296get_terminal_size(PyObject *self, PyObject *args)
11297{
11298 int columns, lines;
11299 PyObject *termsize;
11300
11301 int fd = fileno(stdout);
11302 /* Under some conditions stdout may not be connected and
11303 * fileno(stdout) may point to an invalid file descriptor. For example
11304 * GUI apps don't have valid standard streams by default.
11305 *
11306 * If this happens, and the optional fd argument is not present,
11307 * the ioctl below will fail returning EBADF. This is what we want.
11308 */
11309
11310 if (!PyArg_ParseTuple(args, "|i", &fd))
11311 return NULL;
11312
11313#ifdef TERMSIZE_USE_IOCTL
11314 {
11315 struct winsize w;
11316 if (ioctl(fd, TIOCGWINSZ, &w))
11317 return PyErr_SetFromErrno(PyExc_OSError);
11318 columns = w.ws_col;
11319 lines = w.ws_row;
11320 }
11321#endif /* TERMSIZE_USE_IOCTL */
11322
11323#ifdef TERMSIZE_USE_CONIO
11324 {
11325 DWORD nhandle;
11326 HANDLE handle;
11327 CONSOLE_SCREEN_BUFFER_INFO csbi;
11328 switch (fd) {
11329 case 0: nhandle = STD_INPUT_HANDLE;
11330 break;
11331 case 1: nhandle = STD_OUTPUT_HANDLE;
11332 break;
11333 case 2: nhandle = STD_ERROR_HANDLE;
11334 break;
11335 default:
11336 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11337 }
11338 handle = GetStdHandle(nhandle);
11339 if (handle == NULL)
11340 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11341 if (handle == INVALID_HANDLE_VALUE)
11342 return PyErr_SetFromWindowsErr(0);
11343
11344 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11345 return PyErr_SetFromWindowsErr(0);
11346
11347 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11348 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11349 }
11350#endif /* TERMSIZE_USE_CONIO */
11351
11352 termsize = PyStructSequence_New(&TerminalSizeType);
11353 if (termsize == NULL)
11354 return NULL;
11355 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11356 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11357 if (PyErr_Occurred()) {
11358 Py_DECREF(termsize);
11359 return NULL;
11360 }
11361 return termsize;
11362}
11363#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11364
Larry Hastings2f936352014-08-05 14:04:04 +100011365
11366/*[clinic input]
11367os.cpu_count
11368
Charles-François Natali80d62e62015-08-13 20:37:08 +010011369Return the number of CPUs in the system; return None if indeterminable.
11370
11371This number is not equivalent to the number of CPUs the current process can
11372use. The number of usable CPUs can be obtained with
11373``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011374[clinic start generated code]*/
11375
Larry Hastings2f936352014-08-05 14:04:04 +100011376static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011377os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011378/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011379{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011380 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011381#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011382 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11383 Need to fallback to Vista behavior if this call isn't present */
11384 HINSTANCE hKernel32;
11385 hKernel32 = GetModuleHandleW(L"KERNEL32");
11386
11387 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11388 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11389 "GetMaximumProcessorCount");
11390 if (_GetMaximumProcessorCount != NULL) {
11391 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11392 }
11393 else {
11394 SYSTEM_INFO sysinfo;
11395 GetSystemInfo(&sysinfo);
11396 ncpu = sysinfo.dwNumberOfProcessors;
11397 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011398#elif defined(__hpux)
11399 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11400#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11401 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011402#elif defined(__DragonFly__) || \
11403 defined(__OpenBSD__) || \
11404 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011405 defined(__NetBSD__) || \
11406 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011407 int mib[2];
11408 size_t len = sizeof(ncpu);
11409 mib[0] = CTL_HW;
11410 mib[1] = HW_NCPU;
11411 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11412 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011413#endif
11414 if (ncpu >= 1)
11415 return PyLong_FromLong(ncpu);
11416 else
11417 Py_RETURN_NONE;
11418}
11419
Victor Stinnerdaf45552013-08-28 00:53:59 +020011420
Larry Hastings2f936352014-08-05 14:04:04 +100011421/*[clinic input]
11422os.get_inheritable -> bool
11423
11424 fd: int
11425 /
11426
11427Get the close-on-exe flag of the specified file descriptor.
11428[clinic start generated code]*/
11429
Larry Hastings2f936352014-08-05 14:04:04 +100011430static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011431os_get_inheritable_impl(PyObject *module, int fd)
11432/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011433{
Steve Dower8fc89802015-04-12 00:26:27 -040011434 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011435 _Py_BEGIN_SUPPRESS_IPH
11436 return_value = _Py_get_inheritable(fd);
11437 _Py_END_SUPPRESS_IPH
11438 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011439}
11440
11441
11442/*[clinic input]
11443os.set_inheritable
11444 fd: int
11445 inheritable: int
11446 /
11447
11448Set the inheritable flag of the specified file descriptor.
11449[clinic start generated code]*/
11450
Larry Hastings2f936352014-08-05 14:04:04 +100011451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011452os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11453/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011454{
Steve Dower8fc89802015-04-12 00:26:27 -040011455 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011456
Steve Dower8fc89802015-04-12 00:26:27 -040011457 _Py_BEGIN_SUPPRESS_IPH
11458 result = _Py_set_inheritable(fd, inheritable, NULL);
11459 _Py_END_SUPPRESS_IPH
11460 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011461 return NULL;
11462 Py_RETURN_NONE;
11463}
11464
11465
11466#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011467/*[clinic input]
11468os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011469 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011470 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011471
Larry Hastings2f936352014-08-05 14:04:04 +100011472Get the close-on-exe flag of the specified file descriptor.
11473[clinic start generated code]*/
11474
Larry Hastings2f936352014-08-05 14:04:04 +100011475static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011476os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011477/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011478{
11479 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011480
11481 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11482 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011483 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011484 }
11485
Larry Hastings2f936352014-08-05 14:04:04 +100011486 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011487}
11488
Victor Stinnerdaf45552013-08-28 00:53:59 +020011489
Larry Hastings2f936352014-08-05 14:04:04 +100011490/*[clinic input]
11491os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011492 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011493 inheritable: bool
11494 /
11495
11496Set the inheritable flag of the specified handle.
11497[clinic start generated code]*/
11498
Larry Hastings2f936352014-08-05 14:04:04 +100011499static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011500os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011501 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011502/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011503{
11504 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011505 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11506 PyErr_SetFromWindowsErr(0);
11507 return NULL;
11508 }
11509 Py_RETURN_NONE;
11510}
Larry Hastings2f936352014-08-05 14:04:04 +100011511#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011512
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011513#ifndef MS_WINDOWS
11514PyDoc_STRVAR(get_blocking__doc__,
11515 "get_blocking(fd) -> bool\n" \
11516 "\n" \
11517 "Get the blocking mode of the file descriptor:\n" \
11518 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11519
11520static PyObject*
11521posix_get_blocking(PyObject *self, PyObject *args)
11522{
11523 int fd;
11524 int blocking;
11525
11526 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11527 return NULL;
11528
Steve Dower8fc89802015-04-12 00:26:27 -040011529 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011530 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011531 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011532 if (blocking < 0)
11533 return NULL;
11534 return PyBool_FromLong(blocking);
11535}
11536
11537PyDoc_STRVAR(set_blocking__doc__,
11538 "set_blocking(fd, blocking)\n" \
11539 "\n" \
11540 "Set the blocking mode of the specified file descriptor.\n" \
11541 "Set the O_NONBLOCK flag if blocking is False,\n" \
11542 "clear the O_NONBLOCK flag otherwise.");
11543
11544static PyObject*
11545posix_set_blocking(PyObject *self, PyObject *args)
11546{
Steve Dower8fc89802015-04-12 00:26:27 -040011547 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011548
11549 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11550 return NULL;
11551
Steve Dower8fc89802015-04-12 00:26:27 -040011552 _Py_BEGIN_SUPPRESS_IPH
11553 result = _Py_set_blocking(fd, blocking);
11554 _Py_END_SUPPRESS_IPH
11555 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011556 return NULL;
11557 Py_RETURN_NONE;
11558}
11559#endif /* !MS_WINDOWS */
11560
11561
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011562/*[clinic input]
11563class os.DirEntry "DirEntry *" "&DirEntryType"
11564[clinic start generated code]*/
11565/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011566
11567typedef struct {
11568 PyObject_HEAD
11569 PyObject *name;
11570 PyObject *path;
11571 PyObject *stat;
11572 PyObject *lstat;
11573#ifdef MS_WINDOWS
11574 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011575 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011576 int got_file_index;
11577#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011578#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011579 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011580#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011581 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011582 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011583#endif
11584} DirEntry;
11585
11586static void
11587DirEntry_dealloc(DirEntry *entry)
11588{
11589 Py_XDECREF(entry->name);
11590 Py_XDECREF(entry->path);
11591 Py_XDECREF(entry->stat);
11592 Py_XDECREF(entry->lstat);
11593 Py_TYPE(entry)->tp_free((PyObject *)entry);
11594}
11595
11596/* Forward reference */
11597static int
11598DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11599
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011600/*[clinic input]
11601os.DirEntry.is_symlink -> bool
11602
11603Return True if the entry is a symbolic link; cached per entry.
11604[clinic start generated code]*/
11605
Victor Stinner6036e442015-03-08 01:58:04 +010011606static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011607os_DirEntry_is_symlink_impl(DirEntry *self)
11608/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011609{
11610#ifdef MS_WINDOWS
11611 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011612#elif defined(HAVE_DIRENT_D_TYPE)
11613 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011614 if (self->d_type != DT_UNKNOWN)
11615 return self->d_type == DT_LNK;
11616 else
11617 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011618#else
11619 /* POSIX without d_type */
11620 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011621#endif
11622}
11623
11624static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011625DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11626{
11627 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011628 STRUCT_STAT st;
11629 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011630
11631#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011632 if (!PyUnicode_FSDecoder(self->path, &ub))
11633 return NULL;
11634 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011635#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011636 if (!PyUnicode_FSConverter(self->path, &ub))
11637 return NULL;
11638 const char *path = PyBytes_AS_STRING(ub);
11639 if (self->dir_fd != DEFAULT_DIR_FD) {
11640#ifdef HAVE_FSTATAT
11641 result = fstatat(self->dir_fd, path, &st,
11642 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11643#else
11644 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11645 return NULL;
11646#endif /* HAVE_FSTATAT */
11647 }
11648 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011649#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011650 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011651 if (follow_symlinks)
11652 result = STAT(path, &st);
11653 else
11654 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011655 }
11656 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011657
11658 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011659 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011660
11661 return _pystat_fromstructstat(&st);
11662}
11663
11664static PyObject *
11665DirEntry_get_lstat(DirEntry *self)
11666{
11667 if (!self->lstat) {
11668#ifdef MS_WINDOWS
11669 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11670#else /* POSIX */
11671 self->lstat = DirEntry_fetch_stat(self, 0);
11672#endif
11673 }
11674 Py_XINCREF(self->lstat);
11675 return self->lstat;
11676}
11677
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011678/*[clinic input]
11679os.DirEntry.stat
11680 *
11681 follow_symlinks: bool = True
11682
11683Return stat_result object for the entry; cached per entry.
11684[clinic start generated code]*/
11685
Victor Stinner6036e442015-03-08 01:58:04 +010011686static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011687os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11688/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011689{
11690 if (!follow_symlinks)
11691 return DirEntry_get_lstat(self);
11692
11693 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011694 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011695 if (result == -1)
11696 return NULL;
11697 else if (result)
11698 self->stat = DirEntry_fetch_stat(self, 1);
11699 else
11700 self->stat = DirEntry_get_lstat(self);
11701 }
11702
11703 Py_XINCREF(self->stat);
11704 return self->stat;
11705}
11706
Victor Stinner6036e442015-03-08 01:58:04 +010011707/* Set exception and return -1 on error, 0 for False, 1 for True */
11708static int
11709DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11710{
11711 PyObject *stat = NULL;
11712 PyObject *st_mode = NULL;
11713 long mode;
11714 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011715#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011716 int is_symlink;
11717 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011718#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011719#ifdef MS_WINDOWS
11720 unsigned long dir_bits;
11721#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011722 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011723
11724#ifdef MS_WINDOWS
11725 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11726 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011727#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011728 is_symlink = self->d_type == DT_LNK;
11729 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11730#endif
11731
Victor Stinner35a97c02015-03-08 02:59:09 +010011732#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011733 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011734#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011735 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011736 if (!stat) {
11737 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11738 /* If file doesn't exist (anymore), then return False
11739 (i.e., say it's not a file/directory) */
11740 PyErr_Clear();
11741 return 0;
11742 }
11743 goto error;
11744 }
11745 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11746 if (!st_mode)
11747 goto error;
11748
11749 mode = PyLong_AsLong(st_mode);
11750 if (mode == -1 && PyErr_Occurred())
11751 goto error;
11752 Py_CLEAR(st_mode);
11753 Py_CLEAR(stat);
11754 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011755#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011756 }
11757 else if (is_symlink) {
11758 assert(mode_bits != S_IFLNK);
11759 result = 0;
11760 }
11761 else {
11762 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11763#ifdef MS_WINDOWS
11764 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11765 if (mode_bits == S_IFDIR)
11766 result = dir_bits != 0;
11767 else
11768 result = dir_bits == 0;
11769#else /* POSIX */
11770 if (mode_bits == S_IFDIR)
11771 result = self->d_type == DT_DIR;
11772 else
11773 result = self->d_type == DT_REG;
11774#endif
11775 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011776#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011777
11778 return result;
11779
11780error:
11781 Py_XDECREF(st_mode);
11782 Py_XDECREF(stat);
11783 return -1;
11784}
11785
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011786/*[clinic input]
11787os.DirEntry.is_dir -> bool
11788 *
11789 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011790
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011791Return True if the entry is a directory; cached per entry.
11792[clinic start generated code]*/
11793
11794static int
11795os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11796/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11797{
11798 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011799}
11800
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011801/*[clinic input]
11802os.DirEntry.is_file -> bool
11803 *
11804 follow_symlinks: bool = True
11805
11806Return True if the entry is a file; cached per entry.
11807[clinic start generated code]*/
11808
11809static int
11810os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11811/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011812{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011813 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011814}
11815
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011816/*[clinic input]
11817os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011818
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011819Return inode of the entry; cached per entry.
11820[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011821
11822static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011823os_DirEntry_inode_impl(DirEntry *self)
11824/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011825{
11826#ifdef MS_WINDOWS
11827 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011828 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011829 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011830 STRUCT_STAT stat;
11831 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011832
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011833 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011834 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011835 path = PyUnicode_AsUnicode(unicode);
11836 result = LSTAT(path, &stat);
11837 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011838
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011839 if (result != 0)
11840 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011841
11842 self->win32_file_index = stat.st_ino;
11843 self->got_file_index = 1;
11844 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011845 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11846 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011847#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011848 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11849 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011850#endif
11851}
11852
11853static PyObject *
11854DirEntry_repr(DirEntry *self)
11855{
11856 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11857}
11858
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011859/*[clinic input]
11860os.DirEntry.__fspath__
11861
11862Returns the path for the entry.
11863[clinic start generated code]*/
11864
Brett Cannon96881cd2016-06-10 14:37:21 -070011865static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011866os_DirEntry___fspath___impl(DirEntry *self)
11867/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011868{
11869 Py_INCREF(self->path);
11870 return self->path;
11871}
11872
Victor Stinner6036e442015-03-08 01:58:04 +010011873static PyMemberDef DirEntry_members[] = {
11874 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11875 "the entry's base filename, relative to scandir() \"path\" argument"},
11876 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11877 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11878 {NULL}
11879};
11880
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011881#include "clinic/posixmodule.c.h"
11882
Victor Stinner6036e442015-03-08 01:58:04 +010011883static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011884 OS_DIRENTRY_IS_DIR_METHODDEF
11885 OS_DIRENTRY_IS_FILE_METHODDEF
11886 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11887 OS_DIRENTRY_STAT_METHODDEF
11888 OS_DIRENTRY_INODE_METHODDEF
11889 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011890 {NULL}
11891};
11892
Benjamin Peterson5646de42015-04-12 17:56:34 -040011893static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011894 PyVarObject_HEAD_INIT(NULL, 0)
11895 MODNAME ".DirEntry", /* tp_name */
11896 sizeof(DirEntry), /* tp_basicsize */
11897 0, /* tp_itemsize */
11898 /* methods */
11899 (destructor)DirEntry_dealloc, /* tp_dealloc */
11900 0, /* tp_print */
11901 0, /* tp_getattr */
11902 0, /* tp_setattr */
11903 0, /* tp_compare */
11904 (reprfunc)DirEntry_repr, /* tp_repr */
11905 0, /* tp_as_number */
11906 0, /* tp_as_sequence */
11907 0, /* tp_as_mapping */
11908 0, /* tp_hash */
11909 0, /* tp_call */
11910 0, /* tp_str */
11911 0, /* tp_getattro */
11912 0, /* tp_setattro */
11913 0, /* tp_as_buffer */
11914 Py_TPFLAGS_DEFAULT, /* tp_flags */
11915 0, /* tp_doc */
11916 0, /* tp_traverse */
11917 0, /* tp_clear */
11918 0, /* tp_richcompare */
11919 0, /* tp_weaklistoffset */
11920 0, /* tp_iter */
11921 0, /* tp_iternext */
11922 DirEntry_methods, /* tp_methods */
11923 DirEntry_members, /* tp_members */
11924};
11925
11926#ifdef MS_WINDOWS
11927
11928static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011929join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011930{
11931 Py_ssize_t path_len;
11932 Py_ssize_t size;
11933 wchar_t *result;
11934 wchar_t ch;
11935
11936 if (!path_wide) { /* Default arg: "." */
11937 path_wide = L".";
11938 path_len = 1;
11939 }
11940 else {
11941 path_len = wcslen(path_wide);
11942 }
11943
11944 /* The +1's are for the path separator and the NUL */
11945 size = path_len + 1 + wcslen(filename) + 1;
11946 result = PyMem_New(wchar_t, size);
11947 if (!result) {
11948 PyErr_NoMemory();
11949 return NULL;
11950 }
11951 wcscpy(result, path_wide);
11952 if (path_len > 0) {
11953 ch = result[path_len - 1];
11954 if (ch != SEP && ch != ALTSEP && ch != L':')
11955 result[path_len++] = SEP;
11956 wcscpy(result + path_len, filename);
11957 }
11958 return result;
11959}
11960
11961static PyObject *
11962DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11963{
11964 DirEntry *entry;
11965 BY_HANDLE_FILE_INFORMATION file_info;
11966 ULONG reparse_tag;
11967 wchar_t *joined_path;
11968
11969 entry = PyObject_New(DirEntry, &DirEntryType);
11970 if (!entry)
11971 return NULL;
11972 entry->name = NULL;
11973 entry->path = NULL;
11974 entry->stat = NULL;
11975 entry->lstat = NULL;
11976 entry->got_file_index = 0;
11977
11978 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11979 if (!entry->name)
11980 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011981 if (path->narrow) {
11982 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11983 if (!entry->name)
11984 goto error;
11985 }
Victor Stinner6036e442015-03-08 01:58:04 +010011986
11987 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11988 if (!joined_path)
11989 goto error;
11990
11991 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11992 PyMem_Free(joined_path);
11993 if (!entry->path)
11994 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011995 if (path->narrow) {
11996 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11997 if (!entry->path)
11998 goto error;
11999 }
Victor Stinner6036e442015-03-08 01:58:04 +010012000
Steve Dowercc16be82016-09-08 10:35:16 -070012001 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012002 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12003
12004 return (PyObject *)entry;
12005
12006error:
12007 Py_DECREF(entry);
12008 return NULL;
12009}
12010
12011#else /* POSIX */
12012
12013static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012014join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012015{
12016 Py_ssize_t path_len;
12017 Py_ssize_t size;
12018 char *result;
12019
12020 if (!path_narrow) { /* Default arg: "." */
12021 path_narrow = ".";
12022 path_len = 1;
12023 }
12024 else {
12025 path_len = strlen(path_narrow);
12026 }
12027
12028 if (filename_len == -1)
12029 filename_len = strlen(filename);
12030
12031 /* The +1's are for the path separator and the NUL */
12032 size = path_len + 1 + filename_len + 1;
12033 result = PyMem_New(char, size);
12034 if (!result) {
12035 PyErr_NoMemory();
12036 return NULL;
12037 }
12038 strcpy(result, path_narrow);
12039 if (path_len > 0 && result[path_len - 1] != '/')
12040 result[path_len++] = '/';
12041 strcpy(result + path_len, filename);
12042 return result;
12043}
12044
12045static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012046DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012047 ino_t d_ino
12048#ifdef HAVE_DIRENT_D_TYPE
12049 , unsigned char d_type
12050#endif
12051 )
Victor Stinner6036e442015-03-08 01:58:04 +010012052{
12053 DirEntry *entry;
12054 char *joined_path;
12055
12056 entry = PyObject_New(DirEntry, &DirEntryType);
12057 if (!entry)
12058 return NULL;
12059 entry->name = NULL;
12060 entry->path = NULL;
12061 entry->stat = NULL;
12062 entry->lstat = NULL;
12063
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012064 if (path->fd != -1) {
12065 entry->dir_fd = path->fd;
12066 joined_path = NULL;
12067 }
12068 else {
12069 entry->dir_fd = DEFAULT_DIR_FD;
12070 joined_path = join_path_filename(path->narrow, name, name_len);
12071 if (!joined_path)
12072 goto error;
12073 }
Victor Stinner6036e442015-03-08 01:58:04 +010012074
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012075 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012076 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012077 if (joined_path)
12078 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012079 }
12080 else {
12081 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012082 if (joined_path)
12083 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012084 }
12085 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012086 if (!entry->name)
12087 goto error;
12088
12089 if (path->fd != -1) {
12090 entry->path = entry->name;
12091 Py_INCREF(entry->path);
12092 }
12093 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012094 goto error;
12095
Victor Stinner35a97c02015-03-08 02:59:09 +010012096#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012097 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012098#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012099 entry->d_ino = d_ino;
12100
12101 return (PyObject *)entry;
12102
12103error:
12104 Py_XDECREF(entry);
12105 return NULL;
12106}
12107
12108#endif
12109
12110
12111typedef struct {
12112 PyObject_HEAD
12113 path_t path;
12114#ifdef MS_WINDOWS
12115 HANDLE handle;
12116 WIN32_FIND_DATAW file_data;
12117 int first_time;
12118#else /* POSIX */
12119 DIR *dirp;
12120#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012121#ifdef HAVE_FDOPENDIR
12122 int fd;
12123#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012124} ScandirIterator;
12125
12126#ifdef MS_WINDOWS
12127
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012128static int
12129ScandirIterator_is_closed(ScandirIterator *iterator)
12130{
12131 return iterator->handle == INVALID_HANDLE_VALUE;
12132}
12133
Victor Stinner6036e442015-03-08 01:58:04 +010012134static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012135ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012136{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012137 HANDLE handle = iterator->handle;
12138
12139 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012140 return;
12141
Victor Stinner6036e442015-03-08 01:58:04 +010012142 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012143 Py_BEGIN_ALLOW_THREADS
12144 FindClose(handle);
12145 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012146}
12147
12148static PyObject *
12149ScandirIterator_iternext(ScandirIterator *iterator)
12150{
12151 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12152 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012153 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012154
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012155 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012156 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012157 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012158
12159 while (1) {
12160 if (!iterator->first_time) {
12161 Py_BEGIN_ALLOW_THREADS
12162 success = FindNextFileW(iterator->handle, file_data);
12163 Py_END_ALLOW_THREADS
12164 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012165 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012166 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012167 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012168 break;
12169 }
12170 }
12171 iterator->first_time = 0;
12172
12173 /* Skip over . and .. */
12174 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012175 wcscmp(file_data->cFileName, L"..") != 0) {
12176 entry = DirEntry_from_find_data(&iterator->path, file_data);
12177 if (!entry)
12178 break;
12179 return entry;
12180 }
Victor Stinner6036e442015-03-08 01:58:04 +010012181
12182 /* Loop till we get a non-dot directory or finish iterating */
12183 }
12184
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012185 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012186 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012187 return NULL;
12188}
12189
12190#else /* POSIX */
12191
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012192static int
12193ScandirIterator_is_closed(ScandirIterator *iterator)
12194{
12195 return !iterator->dirp;
12196}
12197
Victor Stinner6036e442015-03-08 01:58:04 +010012198static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012199ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012200{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012201 DIR *dirp = iterator->dirp;
12202
12203 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012204 return;
12205
Victor Stinner6036e442015-03-08 01:58:04 +010012206 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012207 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012208#ifdef HAVE_FDOPENDIR
12209 if (iterator->path.fd != -1)
12210 rewinddir(dirp);
12211#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012212 closedir(dirp);
12213 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012214 return;
12215}
12216
12217static PyObject *
12218ScandirIterator_iternext(ScandirIterator *iterator)
12219{
12220 struct dirent *direntp;
12221 Py_ssize_t name_len;
12222 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012223 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012224
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012225 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012226 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012227 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012228
12229 while (1) {
12230 errno = 0;
12231 Py_BEGIN_ALLOW_THREADS
12232 direntp = readdir(iterator->dirp);
12233 Py_END_ALLOW_THREADS
12234
12235 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012236 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012237 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012238 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012239 break;
12240 }
12241
12242 /* Skip over . and .. */
12243 name_len = NAMLEN(direntp);
12244 is_dot = direntp->d_name[0] == '.' &&
12245 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12246 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012247 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012248 name_len, direntp->d_ino
12249#ifdef HAVE_DIRENT_D_TYPE
12250 , direntp->d_type
12251#endif
12252 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012253 if (!entry)
12254 break;
12255 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012256 }
12257
12258 /* Loop till we get a non-dot directory or finish iterating */
12259 }
12260
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012261 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012262 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012263 return NULL;
12264}
12265
12266#endif
12267
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012268static PyObject *
12269ScandirIterator_close(ScandirIterator *self, PyObject *args)
12270{
12271 ScandirIterator_closedir(self);
12272 Py_RETURN_NONE;
12273}
12274
12275static PyObject *
12276ScandirIterator_enter(PyObject *self, PyObject *args)
12277{
12278 Py_INCREF(self);
12279 return self;
12280}
12281
12282static PyObject *
12283ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12284{
12285 ScandirIterator_closedir(self);
12286 Py_RETURN_NONE;
12287}
12288
Victor Stinner6036e442015-03-08 01:58:04 +010012289static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012290ScandirIterator_finalize(ScandirIterator *iterator)
12291{
12292 PyObject *error_type, *error_value, *error_traceback;
12293
12294 /* Save the current exception, if any. */
12295 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12296
12297 if (!ScandirIterator_is_closed(iterator)) {
12298 ScandirIterator_closedir(iterator);
12299
12300 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12301 "unclosed scandir iterator %R", iterator)) {
12302 /* Spurious errors can appear at shutdown */
12303 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12304 PyErr_WriteUnraisable((PyObject *) iterator);
12305 }
12306 }
12307 }
12308
Victor Stinner7bfa4092016-03-23 00:43:54 +010012309 path_cleanup(&iterator->path);
12310
12311 /* Restore the saved exception. */
12312 PyErr_Restore(error_type, error_value, error_traceback);
12313}
12314
12315static void
Victor Stinner6036e442015-03-08 01:58:04 +010012316ScandirIterator_dealloc(ScandirIterator *iterator)
12317{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012318 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12319 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012320
Victor Stinner6036e442015-03-08 01:58:04 +010012321 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12322}
12323
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012324static PyMethodDef ScandirIterator_methods[] = {
12325 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12326 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12327 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12328 {NULL}
12329};
12330
Benjamin Peterson5646de42015-04-12 17:56:34 -040012331static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012332 PyVarObject_HEAD_INIT(NULL, 0)
12333 MODNAME ".ScandirIterator", /* tp_name */
12334 sizeof(ScandirIterator), /* tp_basicsize */
12335 0, /* tp_itemsize */
12336 /* methods */
12337 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12338 0, /* tp_print */
12339 0, /* tp_getattr */
12340 0, /* tp_setattr */
12341 0, /* tp_compare */
12342 0, /* tp_repr */
12343 0, /* tp_as_number */
12344 0, /* tp_as_sequence */
12345 0, /* tp_as_mapping */
12346 0, /* tp_hash */
12347 0, /* tp_call */
12348 0, /* tp_str */
12349 0, /* tp_getattro */
12350 0, /* tp_setattro */
12351 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012352 Py_TPFLAGS_DEFAULT
12353 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012354 0, /* tp_doc */
12355 0, /* tp_traverse */
12356 0, /* tp_clear */
12357 0, /* tp_richcompare */
12358 0, /* tp_weaklistoffset */
12359 PyObject_SelfIter, /* tp_iter */
12360 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012361 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012362 0, /* tp_members */
12363 0, /* tp_getset */
12364 0, /* tp_base */
12365 0, /* tp_dict */
12366 0, /* tp_descr_get */
12367 0, /* tp_descr_set */
12368 0, /* tp_dictoffset */
12369 0, /* tp_init */
12370 0, /* tp_alloc */
12371 0, /* tp_new */
12372 0, /* tp_free */
12373 0, /* tp_is_gc */
12374 0, /* tp_bases */
12375 0, /* tp_mro */
12376 0, /* tp_cache */
12377 0, /* tp_subclasses */
12378 0, /* tp_weaklist */
12379 0, /* tp_del */
12380 0, /* tp_version_tag */
12381 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012382};
12383
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012384/*[clinic input]
12385os.scandir
12386
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012387 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012388
12389Return an iterator of DirEntry objects for given path.
12390
BNMetrics08026b12018-11-02 17:56:25 +000012391path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012392is bytes, the names of yielded DirEntry objects will also be bytes; in
12393all other circumstances they will be str.
12394
12395If path is None, uses the path='.'.
12396[clinic start generated code]*/
12397
Victor Stinner6036e442015-03-08 01:58:04 +010012398static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012399os_scandir_impl(PyObject *module, path_t *path)
BNMetrics08026b12018-11-02 17:56:25 +000012400/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012401{
12402 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012403#ifdef MS_WINDOWS
12404 wchar_t *path_strW;
12405#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012406 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012407#ifdef HAVE_FDOPENDIR
12408 int fd = -1;
12409#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012410#endif
12411
12412 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12413 if (!iterator)
12414 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012415
12416#ifdef MS_WINDOWS
12417 iterator->handle = INVALID_HANDLE_VALUE;
12418#else
12419 iterator->dirp = NULL;
12420#endif
12421
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012422 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012423 /* Move the ownership to iterator->path */
12424 path->object = NULL;
12425 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012426
12427#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012428 iterator->first_time = 1;
12429
12430 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12431 if (!path_strW)
12432 goto error;
12433
12434 Py_BEGIN_ALLOW_THREADS
12435 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12436 Py_END_ALLOW_THREADS
12437
12438 PyMem_Free(path_strW);
12439
12440 if (iterator->handle == INVALID_HANDLE_VALUE) {
12441 path_error(&iterator->path);
12442 goto error;
12443 }
12444#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012445 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012446#ifdef HAVE_FDOPENDIR
12447 if (path->fd != -1) {
12448 /* closedir() closes the FD, so we duplicate it */
12449 fd = _Py_dup(path->fd);
12450 if (fd == -1)
12451 goto error;
12452
12453 Py_BEGIN_ALLOW_THREADS
12454 iterator->dirp = fdopendir(fd);
12455 Py_END_ALLOW_THREADS
12456 }
12457 else
12458#endif
12459 {
12460 if (iterator->path.narrow)
12461 path_str = iterator->path.narrow;
12462 else
12463 path_str = ".";
12464
12465 Py_BEGIN_ALLOW_THREADS
12466 iterator->dirp = opendir(path_str);
12467 Py_END_ALLOW_THREADS
12468 }
Victor Stinner6036e442015-03-08 01:58:04 +010012469
12470 if (!iterator->dirp) {
12471 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012472#ifdef HAVE_FDOPENDIR
12473 if (fd != -1) {
12474 Py_BEGIN_ALLOW_THREADS
12475 close(fd);
12476 Py_END_ALLOW_THREADS
12477 }
12478#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012479 goto error;
12480 }
12481#endif
12482
12483 return (PyObject *)iterator;
12484
12485error:
12486 Py_DECREF(iterator);
12487 return NULL;
12488}
12489
Ethan Furman410ef8e2016-06-04 12:06:26 -070012490/*
12491 Return the file system path representation of the object.
12492
12493 If the object is str or bytes, then allow it to pass through with
12494 an incremented refcount. If the object defines __fspath__(), then
12495 return the result of that method. All other types raise a TypeError.
12496*/
12497PyObject *
12498PyOS_FSPath(PyObject *path)
12499{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012500 /* For error message reasons, this function is manually inlined in
12501 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012502 _Py_IDENTIFIER(__fspath__);
12503 PyObject *func = NULL;
12504 PyObject *path_repr = NULL;
12505
12506 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12507 Py_INCREF(path);
12508 return path;
12509 }
12510
12511 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12512 if (NULL == func) {
12513 return PyErr_Format(PyExc_TypeError,
12514 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012515 "not %.200s",
12516 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012517 }
12518
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012519 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012520 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012521 if (NULL == path_repr) {
12522 return NULL;
12523 }
12524
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012525 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12526 PyErr_Format(PyExc_TypeError,
12527 "expected %.200s.__fspath__() to return str or bytes, "
12528 "not %.200s", Py_TYPE(path)->tp_name,
12529 Py_TYPE(path_repr)->tp_name);
12530 Py_DECREF(path_repr);
12531 return NULL;
12532 }
12533
Ethan Furman410ef8e2016-06-04 12:06:26 -070012534 return path_repr;
12535}
12536
12537/*[clinic input]
12538os.fspath
12539
12540 path: object
12541
12542Return the file system path representation of the object.
12543
Brett Cannonb4f43e92016-06-09 14:32:08 -070012544If the object is str or bytes, then allow it to pass through as-is. If the
12545object defines __fspath__(), then return the result of that method. All other
12546types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012547[clinic start generated code]*/
12548
12549static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012550os_fspath_impl(PyObject *module, PyObject *path)
12551/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012552{
12553 return PyOS_FSPath(path);
12554}
Victor Stinner6036e442015-03-08 01:58:04 +010012555
Victor Stinner9b1f4742016-09-06 16:18:52 -070012556#ifdef HAVE_GETRANDOM_SYSCALL
12557/*[clinic input]
12558os.getrandom
12559
12560 size: Py_ssize_t
12561 flags: int=0
12562
12563Obtain a series of random bytes.
12564[clinic start generated code]*/
12565
12566static PyObject *
12567os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12568/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12569{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012570 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012571 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012572
12573 if (size < 0) {
12574 errno = EINVAL;
12575 return posix_error();
12576 }
12577
Victor Stinnerec2319c2016-09-20 23:00:59 +020012578 bytes = PyBytes_FromStringAndSize(NULL, size);
12579 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012580 PyErr_NoMemory();
12581 return NULL;
12582 }
12583
12584 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012585 n = syscall(SYS_getrandom,
12586 PyBytes_AS_STRING(bytes),
12587 PyBytes_GET_SIZE(bytes),
12588 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012589 if (n < 0 && errno == EINTR) {
12590 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012591 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012592 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012593
12594 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012595 continue;
12596 }
12597 break;
12598 }
12599
12600 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012601 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012602 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012603 }
12604
Victor Stinnerec2319c2016-09-20 23:00:59 +020012605 if (n != size) {
12606 _PyBytes_Resize(&bytes, n);
12607 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012608
12609 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012610
12611error:
12612 Py_DECREF(bytes);
12613 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012614}
12615#endif /* HAVE_GETRANDOM_SYSCALL */
12616
Larry Hastings31826802013-10-19 00:09:25 -070012617
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012618static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012619
12620 OS_STAT_METHODDEF
12621 OS_ACCESS_METHODDEF
12622 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012623 OS_CHDIR_METHODDEF
12624 OS_CHFLAGS_METHODDEF
12625 OS_CHMOD_METHODDEF
12626 OS_FCHMOD_METHODDEF
12627 OS_LCHMOD_METHODDEF
12628 OS_CHOWN_METHODDEF
12629 OS_FCHOWN_METHODDEF
12630 OS_LCHOWN_METHODDEF
12631 OS_LCHFLAGS_METHODDEF
12632 OS_CHROOT_METHODDEF
12633 OS_CTERMID_METHODDEF
12634 OS_GETCWD_METHODDEF
12635 OS_GETCWDB_METHODDEF
12636 OS_LINK_METHODDEF
12637 OS_LISTDIR_METHODDEF
12638 OS_LSTAT_METHODDEF
12639 OS_MKDIR_METHODDEF
12640 OS_NICE_METHODDEF
12641 OS_GETPRIORITY_METHODDEF
12642 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012643#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012644 {"readlink", (PyCFunction)posix_readlink,
12645 METH_VARARGS | METH_KEYWORDS,
12646 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012647#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012648#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012649 {"readlink", (PyCFunction)win_readlink,
12650 METH_VARARGS | METH_KEYWORDS,
12651 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012652#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012653 OS_RENAME_METHODDEF
12654 OS_REPLACE_METHODDEF
12655 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012656 OS_SYMLINK_METHODDEF
12657 OS_SYSTEM_METHODDEF
12658 OS_UMASK_METHODDEF
12659 OS_UNAME_METHODDEF
12660 OS_UNLINK_METHODDEF
12661 OS_REMOVE_METHODDEF
12662 OS_UTIME_METHODDEF
12663 OS_TIMES_METHODDEF
12664 OS__EXIT_METHODDEF
12665 OS_EXECV_METHODDEF
12666 OS_EXECVE_METHODDEF
12667 OS_SPAWNV_METHODDEF
12668 OS_SPAWNVE_METHODDEF
12669 OS_FORK1_METHODDEF
12670 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012671 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012672 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12673 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12674 OS_SCHED_GETPARAM_METHODDEF
12675 OS_SCHED_GETSCHEDULER_METHODDEF
12676 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12677 OS_SCHED_SETPARAM_METHODDEF
12678 OS_SCHED_SETSCHEDULER_METHODDEF
12679 OS_SCHED_YIELD_METHODDEF
12680 OS_SCHED_SETAFFINITY_METHODDEF
12681 OS_SCHED_GETAFFINITY_METHODDEF
12682 OS_OPENPTY_METHODDEF
12683 OS_FORKPTY_METHODDEF
12684 OS_GETEGID_METHODDEF
12685 OS_GETEUID_METHODDEF
12686 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012687#ifdef HAVE_GETGROUPLIST
12688 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12689#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012690 OS_GETGROUPS_METHODDEF
12691 OS_GETPID_METHODDEF
12692 OS_GETPGRP_METHODDEF
12693 OS_GETPPID_METHODDEF
12694 OS_GETUID_METHODDEF
12695 OS_GETLOGIN_METHODDEF
12696 OS_KILL_METHODDEF
12697 OS_KILLPG_METHODDEF
12698 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012699#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012700 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012701#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012702 OS_SETUID_METHODDEF
12703 OS_SETEUID_METHODDEF
12704 OS_SETREUID_METHODDEF
12705 OS_SETGID_METHODDEF
12706 OS_SETEGID_METHODDEF
12707 OS_SETREGID_METHODDEF
12708 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012709#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012710 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012711#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012712 OS_GETPGID_METHODDEF
12713 OS_SETPGRP_METHODDEF
12714 OS_WAIT_METHODDEF
12715 OS_WAIT3_METHODDEF
12716 OS_WAIT4_METHODDEF
12717 OS_WAITID_METHODDEF
12718 OS_WAITPID_METHODDEF
12719 OS_GETSID_METHODDEF
12720 OS_SETSID_METHODDEF
12721 OS_SETPGID_METHODDEF
12722 OS_TCGETPGRP_METHODDEF
12723 OS_TCSETPGRP_METHODDEF
12724 OS_OPEN_METHODDEF
12725 OS_CLOSE_METHODDEF
12726 OS_CLOSERANGE_METHODDEF
12727 OS_DEVICE_ENCODING_METHODDEF
12728 OS_DUP_METHODDEF
12729 OS_DUP2_METHODDEF
12730 OS_LOCKF_METHODDEF
12731 OS_LSEEK_METHODDEF
12732 OS_READ_METHODDEF
12733 OS_READV_METHODDEF
12734 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012735 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012736 OS_WRITE_METHODDEF
12737 OS_WRITEV_METHODDEF
12738 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012739 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012740#ifdef HAVE_SENDFILE
12741 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12742 posix_sendfile__doc__},
12743#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012744 OS_FSTAT_METHODDEF
12745 OS_ISATTY_METHODDEF
12746 OS_PIPE_METHODDEF
12747 OS_PIPE2_METHODDEF
12748 OS_MKFIFO_METHODDEF
12749 OS_MKNOD_METHODDEF
12750 OS_MAJOR_METHODDEF
12751 OS_MINOR_METHODDEF
12752 OS_MAKEDEV_METHODDEF
12753 OS_FTRUNCATE_METHODDEF
12754 OS_TRUNCATE_METHODDEF
12755 OS_POSIX_FALLOCATE_METHODDEF
12756 OS_POSIX_FADVISE_METHODDEF
12757 OS_PUTENV_METHODDEF
12758 OS_UNSETENV_METHODDEF
12759 OS_STRERROR_METHODDEF
12760 OS_FCHDIR_METHODDEF
12761 OS_FSYNC_METHODDEF
12762 OS_SYNC_METHODDEF
12763 OS_FDATASYNC_METHODDEF
12764 OS_WCOREDUMP_METHODDEF
12765 OS_WIFCONTINUED_METHODDEF
12766 OS_WIFSTOPPED_METHODDEF
12767 OS_WIFSIGNALED_METHODDEF
12768 OS_WIFEXITED_METHODDEF
12769 OS_WEXITSTATUS_METHODDEF
12770 OS_WTERMSIG_METHODDEF
12771 OS_WSTOPSIG_METHODDEF
12772 OS_FSTATVFS_METHODDEF
12773 OS_STATVFS_METHODDEF
12774 OS_CONFSTR_METHODDEF
12775 OS_SYSCONF_METHODDEF
12776 OS_FPATHCONF_METHODDEF
12777 OS_PATHCONF_METHODDEF
12778 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012779 OS__GETFULLPATHNAME_METHODDEF
12780 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012781 OS__GETDISKUSAGE_METHODDEF
12782 OS__GETFINALPATHNAME_METHODDEF
12783 OS__GETVOLUMEPATHNAME_METHODDEF
12784 OS_GETLOADAVG_METHODDEF
12785 OS_URANDOM_METHODDEF
12786 OS_SETRESUID_METHODDEF
12787 OS_SETRESGID_METHODDEF
12788 OS_GETRESUID_METHODDEF
12789 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012790
Larry Hastings2f936352014-08-05 14:04:04 +100012791 OS_GETXATTR_METHODDEF
12792 OS_SETXATTR_METHODDEF
12793 OS_REMOVEXATTR_METHODDEF
12794 OS_LISTXATTR_METHODDEF
12795
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012796#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12797 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12798#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012799 OS_CPU_COUNT_METHODDEF
12800 OS_GET_INHERITABLE_METHODDEF
12801 OS_SET_INHERITABLE_METHODDEF
12802 OS_GET_HANDLE_INHERITABLE_METHODDEF
12803 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012804#ifndef MS_WINDOWS
12805 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12806 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12807#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012808 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012809 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012810 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012811 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012812};
12813
12814
Brian Curtin52173d42010-12-02 18:29:18 +000012815#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012816static int
Brian Curtin52173d42010-12-02 18:29:18 +000012817enable_symlink()
12818{
12819 HANDLE tok;
12820 TOKEN_PRIVILEGES tok_priv;
12821 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012822
12823 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012824 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012825
12826 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012827 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012828
12829 tok_priv.PrivilegeCount = 1;
12830 tok_priv.Privileges[0].Luid = luid;
12831 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12832
12833 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12834 sizeof(TOKEN_PRIVILEGES),
12835 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012836 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012837
Brian Curtin3b4499c2010-12-28 14:31:47 +000012838 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12839 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012840}
12841#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12842
Barry Warsaw4a342091996-12-19 23:50:02 +000012843static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012844all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012845{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012846#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012847 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012848#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012849#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012850 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012851#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012852#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012853 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012854#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012855#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012856 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012857#endif
Fred Drakec9680921999-12-13 16:37:25 +000012858#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012859 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012860#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012861#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012862 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012863#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012864#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012865 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012866#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012867#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012868 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012869#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012870#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012871 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012872#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012873#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012874 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012875#endif
12876#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012877 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012878#endif
12879#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012880 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012881#endif
12882#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012883 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012884#endif
12885#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012886 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012887#endif
12888#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012889 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012890#endif
12891#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012892 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012893#endif
12894#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012895 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012896#endif
12897#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012898 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012899#endif
12900#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012901 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012902#endif
12903#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012904 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012905#endif
12906#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012907 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012908#endif
12909#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012910 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012911#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012912#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012913 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012914#endif
12915#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012916 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012917#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012918#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012919 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012920#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012921#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012922 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012923#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012924#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012925#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012926 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012927#endif
12928#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012929 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012930#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012931#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012932#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012933 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012934#endif
12935#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012936 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012937#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012938#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012939 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012940#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012941#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012942 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012943#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012944#ifdef O_TMPFILE
12945 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12946#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012947#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012948 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012949#endif
12950#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012951 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012952#endif
12953#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012954 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012955#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012956#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012957 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012958#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012959#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012960 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012961#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012962
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012963
Jesus Cea94363612012-06-22 18:32:07 +020012964#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012965 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012966#endif
12967#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012968 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012969#endif
12970
Tim Peters5aa91602002-01-30 05:46:57 +000012971/* MS Windows */
12972#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012973 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012974 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012975#endif
12976#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012977 /* Optimize for short life (keep in memory). */
12978 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012979 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012980#endif
12981#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012982 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012983 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012984#endif
12985#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012986 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012987 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012988#endif
12989#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012990 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012991 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012992#endif
12993
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012994/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012995#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012996 /* Send a SIGIO signal whenever input or output
12997 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012998 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012999#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013000#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013001 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013002 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013003#endif
13004#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013005 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013006 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013007#endif
13008#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013009 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013010 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013011#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013012#ifdef O_NOLINKS
13013 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013014 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013015#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013016#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013017 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013018 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013019#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013020
Victor Stinner8c62be82010-05-06 00:08:46 +000013021 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013022#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013023 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013024#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013025#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013026 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013027#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013028#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013029 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013030#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013031#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013032 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013033#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013034#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013035 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013036#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013037#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013038 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013039#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013040#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013041 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013042#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013043#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013044 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013045#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013046#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013047 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013048#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013049#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013050 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013051#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013052#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013053 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013054#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013055#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013056 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013057#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013058#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013059 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013060#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013061#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013062 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013063#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013064#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013065 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013066#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013067#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013068 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013069#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013070#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013071 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013072#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013073
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013074 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013075#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013076 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013077#endif /* ST_RDONLY */
13078#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013079 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013080#endif /* ST_NOSUID */
13081
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013082 /* GNU extensions */
13083#ifdef ST_NODEV
13084 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13085#endif /* ST_NODEV */
13086#ifdef ST_NOEXEC
13087 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13088#endif /* ST_NOEXEC */
13089#ifdef ST_SYNCHRONOUS
13090 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13091#endif /* ST_SYNCHRONOUS */
13092#ifdef ST_MANDLOCK
13093 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13094#endif /* ST_MANDLOCK */
13095#ifdef ST_WRITE
13096 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13097#endif /* ST_WRITE */
13098#ifdef ST_APPEND
13099 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13100#endif /* ST_APPEND */
13101#ifdef ST_NOATIME
13102 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13103#endif /* ST_NOATIME */
13104#ifdef ST_NODIRATIME
13105 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13106#endif /* ST_NODIRATIME */
13107#ifdef ST_RELATIME
13108 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13109#endif /* ST_RELATIME */
13110
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013111 /* FreeBSD sendfile() constants */
13112#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013113 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013114#endif
13115#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013116 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013117#endif
13118#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013119 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013120#endif
13121
Ross Lagerwall7807c352011-03-17 20:20:30 +020013122 /* constants for posix_fadvise */
13123#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013124 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013125#endif
13126#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013127 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013128#endif
13129#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013130 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013131#endif
13132#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013133 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013134#endif
13135#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013136 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013137#endif
13138#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013139 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013140#endif
13141
13142 /* constants for waitid */
13143#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013144 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13145 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13146 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013147#endif
13148#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013149 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013150#endif
13151#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013152 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013153#endif
13154#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013155 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013156#endif
13157#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013158 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013159#endif
13160#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013161 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013162#endif
13163#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013164 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013165#endif
13166#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013167 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013168#endif
13169
13170 /* constants for lockf */
13171#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013172 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013173#endif
13174#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013175 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013176#endif
13177#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013178 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013179#endif
13180#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013181 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013182#endif
13183
Pablo Galindo4defba32018-01-27 16:16:37 +000013184#ifdef RWF_DSYNC
13185 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13186#endif
13187#ifdef RWF_HIPRI
13188 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13189#endif
13190#ifdef RWF_SYNC
13191 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13192#endif
13193#ifdef RWF_NOWAIT
13194 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13195#endif
13196
Guido van Rossum246bc171999-02-01 23:54:31 +000013197#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013198 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13199 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13200 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13201 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13202 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013203#endif
13204
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013205#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013206#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013207 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013208#endif
13209#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013210 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013211#endif
13212#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013213 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013214#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013215#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013216 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013217#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013218#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013219 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013220#endif
13221#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013222 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013223#endif
13224#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013225 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013226#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013227#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013228 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013229#endif
13230#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013231 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013232#endif
13233#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013234 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013235#endif
13236#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013237 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013238#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013239#endif
13240
Benjamin Peterson9428d532011-09-14 11:45:52 -040013241#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013242 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13243 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13244 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013245#endif
13246
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013247#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013248 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013249#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013250#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013251 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013252#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013253#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013254 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013255#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013256#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013257 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013258#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013259#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013260 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013261#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013262#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013263 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013264#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013265#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013266 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013267#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013268#if HAVE_DECL_RTLD_MEMBER
13269 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13270#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013271
Victor Stinner9b1f4742016-09-06 16:18:52 -070013272#ifdef HAVE_GETRANDOM_SYSCALL
13273 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13274 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13275#endif
13276
Victor Stinner8c62be82010-05-06 00:08:46 +000013277 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013278}
13279
13280
Martin v. Löwis1a214512008-06-11 05:26:20 +000013281static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013282 PyModuleDef_HEAD_INIT,
13283 MODNAME,
13284 posix__doc__,
13285 -1,
13286 posix_methods,
13287 NULL,
13288 NULL,
13289 NULL,
13290 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013291};
13292
13293
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013294static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013295
13296#ifdef HAVE_FACCESSAT
13297 "HAVE_FACCESSAT",
13298#endif
13299
13300#ifdef HAVE_FCHDIR
13301 "HAVE_FCHDIR",
13302#endif
13303
13304#ifdef HAVE_FCHMOD
13305 "HAVE_FCHMOD",
13306#endif
13307
13308#ifdef HAVE_FCHMODAT
13309 "HAVE_FCHMODAT",
13310#endif
13311
13312#ifdef HAVE_FCHOWN
13313 "HAVE_FCHOWN",
13314#endif
13315
Larry Hastings00964ed2013-08-12 13:49:30 -040013316#ifdef HAVE_FCHOWNAT
13317 "HAVE_FCHOWNAT",
13318#endif
13319
Larry Hastings9cf065c2012-06-22 16:30:09 -070013320#ifdef HAVE_FEXECVE
13321 "HAVE_FEXECVE",
13322#endif
13323
13324#ifdef HAVE_FDOPENDIR
13325 "HAVE_FDOPENDIR",
13326#endif
13327
Georg Brandl306336b2012-06-24 12:55:33 +020013328#ifdef HAVE_FPATHCONF
13329 "HAVE_FPATHCONF",
13330#endif
13331
Larry Hastings9cf065c2012-06-22 16:30:09 -070013332#ifdef HAVE_FSTATAT
13333 "HAVE_FSTATAT",
13334#endif
13335
13336#ifdef HAVE_FSTATVFS
13337 "HAVE_FSTATVFS",
13338#endif
13339
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013340#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013341 "HAVE_FTRUNCATE",
13342#endif
13343
Larry Hastings9cf065c2012-06-22 16:30:09 -070013344#ifdef HAVE_FUTIMENS
13345 "HAVE_FUTIMENS",
13346#endif
13347
13348#ifdef HAVE_FUTIMES
13349 "HAVE_FUTIMES",
13350#endif
13351
13352#ifdef HAVE_FUTIMESAT
13353 "HAVE_FUTIMESAT",
13354#endif
13355
13356#ifdef HAVE_LINKAT
13357 "HAVE_LINKAT",
13358#endif
13359
13360#ifdef HAVE_LCHFLAGS
13361 "HAVE_LCHFLAGS",
13362#endif
13363
13364#ifdef HAVE_LCHMOD
13365 "HAVE_LCHMOD",
13366#endif
13367
13368#ifdef HAVE_LCHOWN
13369 "HAVE_LCHOWN",
13370#endif
13371
13372#ifdef HAVE_LSTAT
13373 "HAVE_LSTAT",
13374#endif
13375
13376#ifdef HAVE_LUTIMES
13377 "HAVE_LUTIMES",
13378#endif
13379
13380#ifdef HAVE_MKDIRAT
13381 "HAVE_MKDIRAT",
13382#endif
13383
13384#ifdef HAVE_MKFIFOAT
13385 "HAVE_MKFIFOAT",
13386#endif
13387
13388#ifdef HAVE_MKNODAT
13389 "HAVE_MKNODAT",
13390#endif
13391
13392#ifdef HAVE_OPENAT
13393 "HAVE_OPENAT",
13394#endif
13395
13396#ifdef HAVE_READLINKAT
13397 "HAVE_READLINKAT",
13398#endif
13399
13400#ifdef HAVE_RENAMEAT
13401 "HAVE_RENAMEAT",
13402#endif
13403
13404#ifdef HAVE_SYMLINKAT
13405 "HAVE_SYMLINKAT",
13406#endif
13407
13408#ifdef HAVE_UNLINKAT
13409 "HAVE_UNLINKAT",
13410#endif
13411
13412#ifdef HAVE_UTIMENSAT
13413 "HAVE_UTIMENSAT",
13414#endif
13415
13416#ifdef MS_WINDOWS
13417 "MS_WINDOWS",
13418#endif
13419
13420 NULL
13421};
13422
13423
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013424PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013425INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013426{
Victor Stinner8c62be82010-05-06 00:08:46 +000013427 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013428 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013429 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013430
Brian Curtin52173d42010-12-02 18:29:18 +000013431#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013432 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013433#endif
13434
Victor Stinner8c62be82010-05-06 00:08:46 +000013435 m = PyModule_Create(&posixmodule);
13436 if (m == NULL)
13437 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013438
Victor Stinner8c62be82010-05-06 00:08:46 +000013439 /* Initialize environ dictionary */
13440 v = convertenviron();
13441 Py_XINCREF(v);
13442 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13443 return NULL;
13444 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013445
Victor Stinner8c62be82010-05-06 00:08:46 +000013446 if (all_ins(m))
13447 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013448
Victor Stinner8c62be82010-05-06 00:08:46 +000013449 if (setup_confname_tables(m))
13450 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013451
Victor Stinner8c62be82010-05-06 00:08:46 +000013452 Py_INCREF(PyExc_OSError);
13453 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013454
Guido van Rossumb3d39562000-01-31 18:41:26 +000013455#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013456 if (posix_putenv_garbage == NULL)
13457 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013458#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013459
Victor Stinner8c62be82010-05-06 00:08:46 +000013460 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013461#if defined(HAVE_WAITID) && !defined(__APPLE__)
13462 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013463 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13464 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013465#endif
13466
Christian Heimes25827622013-10-12 01:27:08 +020013467 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013468 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13469 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13470 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013471 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13472 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013473 structseq_new = StatResultType.tp_new;
13474 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013475
Christian Heimes25827622013-10-12 01:27:08 +020013476 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013477 if (PyStructSequence_InitType2(&StatVFSResultType,
13478 &statvfs_result_desc) < 0)
13479 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013480#ifdef NEED_TICKS_PER_SECOND
13481# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013482 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013483# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013484 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013485# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013486 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013487# endif
13488#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013489
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013490#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013491 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013492 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13493 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013494 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013495#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013496
13497 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013498 if (PyStructSequence_InitType2(&TerminalSizeType,
13499 &TerminalSize_desc) < 0)
13500 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013501
13502 /* initialize scandir types */
13503 if (PyType_Ready(&ScandirIteratorType) < 0)
13504 return NULL;
13505 if (PyType_Ready(&DirEntryType) < 0)
13506 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013507 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013508#if defined(HAVE_WAITID) && !defined(__APPLE__)
13509 Py_INCREF((PyObject*) &WaitidResultType);
13510 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13511#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013512 Py_INCREF((PyObject*) &StatResultType);
13513 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13514 Py_INCREF((PyObject*) &StatVFSResultType);
13515 PyModule_AddObject(m, "statvfs_result",
13516 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013517
13518#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013519 Py_INCREF(&SchedParamType);
13520 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013521#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013522
Larry Hastings605a62d2012-06-24 04:33:36 -070013523 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013524 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13525 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013526 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13527
13528 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013529 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13530 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013531 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13532
Thomas Wouters477c8d52006-05-27 19:21:47 +000013533#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013534 /*
13535 * Step 2 of weak-linking support on Mac OS X.
13536 *
13537 * The code below removes functions that are not available on the
13538 * currently active platform.
13539 *
13540 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013541 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013542 * OSX 10.4.
13543 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013544#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013545 if (fstatvfs == NULL) {
13546 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13547 return NULL;
13548 }
13549 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013550#endif /* HAVE_FSTATVFS */
13551
13552#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013553 if (statvfs == NULL) {
13554 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13555 return NULL;
13556 }
13557 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013558#endif /* HAVE_STATVFS */
13559
13560# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013561 if (lchown == NULL) {
13562 if (PyObject_DelAttrString(m, "lchown") == -1) {
13563 return NULL;
13564 }
13565 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013566#endif /* HAVE_LCHOWN */
13567
13568
13569#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013570
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013571 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013572 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13573
Larry Hastings6fe20b32012-04-19 15:07:49 -070013574 billion = PyLong_FromLong(1000000000);
13575 if (!billion)
13576 return NULL;
13577
Larry Hastings9cf065c2012-06-22 16:30:09 -070013578 /* suppress "function not used" warnings */
13579 {
13580 int ignored;
13581 fd_specified("", -1);
13582 follow_symlinks_specified("", 1);
13583 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13584 dir_fd_converter(Py_None, &ignored);
13585 dir_fd_unavailable(Py_None, &ignored);
13586 }
13587
13588 /*
13589 * provide list of locally available functions
13590 * so os.py can populate support_* lists
13591 */
13592 list = PyList_New(0);
13593 if (!list)
13594 return NULL;
13595 for (trace = have_functions; *trace; trace++) {
13596 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13597 if (!unicode)
13598 return NULL;
13599 if (PyList_Append(list, unicode))
13600 return NULL;
13601 Py_DECREF(unicode);
13602 }
13603 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013604
13605 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013606 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013607
13608 initialized = 1;
13609
Victor Stinner8c62be82010-05-06 00:08:46 +000013610 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013611}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013612
13613#ifdef __cplusplus
13614}
13615#endif