blob: aa77094da06a9391fae68b18fcf1d3b6c5285a6d [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
Victor Stinner621cebe2018-11-12 16:53:38 +010035#include "pycore_pystate.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000036
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020037/* On android API level 21, 'AT_EACCESS' is not declared although
38 * HAVE_FACCESSAT is defined. */
39#ifdef __ANDROID__
40#undef HAVE_FACCESSAT
41#endif
42
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000043#include <stdio.h> /* needed for ctermid() */
44
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000045#ifdef __cplusplus
46extern "C" {
47#endif
48
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000049PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000050"This module provides access to operating system functionality that is\n\
51standardized by the C Standard and the POSIX standard (a thinly\n\
52disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000053corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000055
Ross Lagerwall4d076da2011-03-18 06:56:53 +020056#ifdef HAVE_SYS_UIO_H
57#include <sys/uio.h>
58#endif
59
Christian Heimes75b96182017-09-05 15:53:09 +020060#ifdef HAVE_SYS_SYSMACROS_H
61/* GNU C Library: major(), minor(), makedev() */
62#include <sys/sysmacros.h>
63#endif
64
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000066#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000067#endif /* HAVE_SYS_TYPES_H */
68
69#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000070#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000071#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000072
Guido van Rossum36bc6801995-06-14 22:54:23 +000073#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000074#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000075#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000076
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000078#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000079#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000080
Guido van Rossumb6775db1994-08-01 11:34:53 +000081#ifdef HAVE_FCNTL_H
82#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000083#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000084
Guido van Rossuma6535fd2001-10-18 19:44:10 +000085#ifdef HAVE_GRP_H
86#include <grp.h>
87#endif
88
Barry Warsaw5676bd12003-01-07 20:57:09 +000089#ifdef HAVE_SYSEXITS_H
90#include <sysexits.h>
91#endif /* HAVE_SYSEXITS_H */
92
Anthony Baxter8a560de2004-10-13 15:30:56 +000093#ifdef HAVE_SYS_LOADAVG_H
94#include <sys/loadavg.h>
95#endif
96
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000097#ifdef HAVE_SYS_SENDFILE_H
98#include <sys/sendfile.h>
99#endif
100
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200101#if defined(__APPLE__)
102#include <copyfile.h>
103#endif
104
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500105#ifdef HAVE_SCHED_H
106#include <sched.h>
107#endif
108
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500109#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500110#undef HAVE_SCHED_SETAFFINITY
111#endif
112
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200113#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400114#define USE_XATTRS
115#endif
116
117#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400118#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400119#endif
120
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000121#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
122#ifdef HAVE_SYS_SOCKET_H
123#include <sys/socket.h>
124#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000125#endif
126
Victor Stinner8b905bd2011-10-25 13:34:04 +0200127#ifdef HAVE_DLFCN_H
128#include <dlfcn.h>
129#endif
130
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200131#ifdef __hpux
132#include <sys/mpctl.h>
133#endif
134
135#if defined(__DragonFly__) || \
136 defined(__OpenBSD__) || \
137 defined(__FreeBSD__) || \
138 defined(__NetBSD__) || \
139 defined(__APPLE__)
140#include <sys/sysctl.h>
141#endif
142
Victor Stinner9b1f4742016-09-06 16:18:52 -0700143#ifdef HAVE_LINUX_RANDOM_H
144# include <linux/random.h>
145#endif
146#ifdef HAVE_GETRANDOM_SYSCALL
147# include <sys/syscall.h>
148#endif
149
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100150#if defined(MS_WINDOWS)
151# define TERMSIZE_USE_CONIO
152#elif defined(HAVE_SYS_IOCTL_H)
153# include <sys/ioctl.h>
154# if defined(HAVE_TERMIOS_H)
155# include <termios.h>
156# endif
157# if defined(TIOCGWINSZ)
158# define TERMSIZE_USE_IOCTL
159# endif
160#endif /* MS_WINDOWS */
161
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000163/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000166#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000167#include <process.h>
168#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000169#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000170#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000171#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000172#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700174#define HAVE_WSPAWNV 1
175#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000177#define HAVE_SYSTEM 1
178#define HAVE_CWAIT 1
179#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000180#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000181#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182/* Unix functions that the configure script doesn't check for */
183#define HAVE_EXECV 1
184#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000186#define HAVE_FORK1 1
187#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#define HAVE_GETEGID 1
189#define HAVE_GETEUID 1
190#define HAVE_GETGID 1
191#define HAVE_GETPPID 1
192#define HAVE_GETUID 1
193#define HAVE_KILL 1
194#define HAVE_OPENDIR 1
195#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000196#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000197#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000198#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000199#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000200#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000201
Victor Stinnera2f7c002012-02-08 03:36:25 +0100202
Larry Hastings61272b72014-01-07 12:41:53 -0800203/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000204# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800205module os
Larry Hastings61272b72014-01-07 12:41:53 -0800206[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000207/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100208
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000211#if defined(__sgi)&&_COMPILER_VERSION>=700
212/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
213 (default) */
214extern char *ctermid_r(char *);
215#endif
216
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000219#ifdef HAVE_POSIX_SPAWN
220#include <spawn.h>
221#endif
222
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#ifdef HAVE_UTIME_H
224#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000225#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000227#ifdef HAVE_SYS_UTIME_H
228#include <sys/utime.h>
229#define HAVE_UTIME_H /* pretend we do for the rest of this file */
230#endif /* HAVE_SYS_UTIME_H */
231
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#ifdef HAVE_SYS_TIMES_H
233#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000234#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235
236#ifdef HAVE_SYS_PARAM_H
237#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
240#ifdef HAVE_SYS_UTSNAME_H
241#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000242#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#define NAMLEN(dirent) strlen((dirent)->d_name)
247#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000248#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#include <direct.h>
250#define NAMLEN(dirent) strlen((dirent)->d_name)
251#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000253#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000254#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000255#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000257#endif
258#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000260#endif
261#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000263#endif
264#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000266#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000267#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000269#endif
270#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000272#endif
273#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000275#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000276#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000277#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000278#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100279#ifndef IO_REPARSE_TAG_MOUNT_POINT
280#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
281#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000282#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000283#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000285#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000286#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000287#define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000289
Tim Petersbc2e10e2002-03-03 23:17:02 +0000290#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000291#if defined(PATH_MAX) && PATH_MAX > 1024
292#define MAXPATHLEN PATH_MAX
293#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000294#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000295#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000296#endif /* MAXPATHLEN */
297
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000298#ifdef UNION_WAIT
299/* Emulate some macros on systems that have a union instead of macros */
300
301#ifndef WIFEXITED
302#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
303#endif
304
305#ifndef WEXITSTATUS
306#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
307#endif
308
309#ifndef WTERMSIG
310#define WTERMSIG(u_wait) ((u_wait).w_termsig)
311#endif
312
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000313#define WAIT_TYPE union wait
314#define WAIT_STATUS_INT(s) (s.w_status)
315
316#else /* !UNION_WAIT */
317#define WAIT_TYPE int
318#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000319#endif /* UNION_WAIT */
320
Greg Wardb48bc172000-03-01 21:51:56 +0000321/* Don't use the "_r" form if we don't need it (also, won't have a
322 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200323#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000324#define USE_CTERMID_R
325#endif
326
Fred Drake699f3522000-06-29 21:12:41 +0000327/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000328#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000329#undef FSTAT
330#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200331#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000332# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700333# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200334# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800335# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000336#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000337# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700338# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000339# define FSTAT fstat
340# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000341#endif
342
Tim Peters11b23062003-04-23 02:39:17 +0000343#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000344#include <sys/mkdev.h>
345#else
346#if defined(MAJOR_IN_SYSMACROS)
347#include <sys/sysmacros.h>
348#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000349#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
350#include <sys/mkdev.h>
351#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000352#endif
Fred Drake699f3522000-06-29 21:12:41 +0000353
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200354#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100355#define INITFUNC PyInit_nt
356#define MODNAME "nt"
357#else
358#define INITFUNC PyInit_posix
359#define MODNAME "posix"
360#endif
361
jcea6c51d512018-01-28 14:00:08 +0100362#if defined(__sun)
363/* Something to implement in autoconf, not present in autoconf 2.69 */
364#define HAVE_STRUCT_STAT_ST_FSTYPE 1
365#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200366
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800367#ifdef _Py_MEMORY_SANITIZER
368# include <sanitizer/msan_interface.h>
369#endif
370
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200371#ifdef HAVE_FORK
372static void
373run_at_forkers(PyObject *lst, int reverse)
374{
375 Py_ssize_t i;
376 PyObject *cpy;
377
378 if (lst != NULL) {
379 assert(PyList_CheckExact(lst));
380
381 /* Use a list copy in case register_at_fork() is called from
382 * one of the callbacks.
383 */
384 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
385 if (cpy == NULL)
386 PyErr_WriteUnraisable(lst);
387 else {
388 if (reverse)
389 PyList_Reverse(cpy);
390 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
391 PyObject *func, *res;
392 func = PyList_GET_ITEM(cpy, i);
393 res = PyObject_CallObject(func, NULL);
394 if (res == NULL)
395 PyErr_WriteUnraisable(func);
396 else
397 Py_DECREF(res);
398 }
399 Py_DECREF(cpy);
400 }
401 }
402}
403
404void
405PyOS_BeforeFork(void)
406{
Victor Stinnercaba55b2018-08-03 15:33:52 +0200407 run_at_forkers(_PyInterpreterState_Get()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200408
409 _PyImport_AcquireLock();
410}
411
412void
413PyOS_AfterFork_Parent(void)
414{
415 if (_PyImport_ReleaseLock() <= 0)
416 Py_FatalError("failed releasing import lock after fork");
417
Victor Stinnercaba55b2018-08-03 15:33:52 +0200418 run_at_forkers(_PyInterpreterState_Get()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200419}
420
421void
422PyOS_AfterFork_Child(void)
423{
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200424 _PyRuntimeState *runtime = &_PyRuntime;
425 _PyGILState_Reinit(runtime);
426 _PyInterpreterState_DeleteExceptMain(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200427 PyEval_ReInitThreads();
428 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200429 _PySignal_AfterFork();
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200430 _PyRuntimeState_ReInitThreads(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200431
Victor Stinnercaba55b2018-08-03 15:33:52 +0200432 run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200433}
434
435static int
436register_at_forker(PyObject **lst, PyObject *func)
437{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700438 if (func == NULL) /* nothing to register? do nothing. */
439 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200440 if (*lst == NULL) {
441 *lst = PyList_New(0);
442 if (*lst == NULL)
443 return -1;
444 }
445 return PyList_Append(*lst, func);
446}
447#endif
448
449/* Legacy wrapper */
450void
451PyOS_AfterFork(void)
452{
453#ifdef HAVE_FORK
454 PyOS_AfterFork_Child();
455#endif
456}
457
458
Victor Stinner6036e442015-03-08 01:58:04 +0100459#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200460/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700461void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
462void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200463 ULONG, struct _Py_stat_struct *);
464#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700465
466#ifdef MS_WINDOWS
467static int
468win32_warn_bytes_api()
469{
470 return PyErr_WarnEx(PyExc_DeprecationWarning,
471 "The Windows bytes API has been deprecated, "
472 "use Unicode filenames instead",
473 1);
474}
475#endif
476
477
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200478#ifndef MS_WINDOWS
479PyObject *
480_PyLong_FromUid(uid_t uid)
481{
482 if (uid == (uid_t)-1)
483 return PyLong_FromLong(-1);
484 return PyLong_FromUnsignedLong(uid);
485}
486
487PyObject *
488_PyLong_FromGid(gid_t gid)
489{
490 if (gid == (gid_t)-1)
491 return PyLong_FromLong(-1);
492 return PyLong_FromUnsignedLong(gid);
493}
494
495int
496_Py_Uid_Converter(PyObject *obj, void *p)
497{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700498 uid_t uid;
499 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200500 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200501 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700502 unsigned long uresult;
503
504 index = PyNumber_Index(obj);
505 if (index == NULL) {
506 PyErr_Format(PyExc_TypeError,
507 "uid should be integer, not %.200s",
508 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200509 return 0;
510 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700511
512 /*
513 * Handling uid_t is complicated for two reasons:
514 * * Although uid_t is (always?) unsigned, it still
515 * accepts -1.
516 * * We don't know its size in advance--it may be
517 * bigger than an int, or it may be smaller than
518 * a long.
519 *
520 * So a bit of defensive programming is in order.
521 * Start with interpreting the value passed
522 * in as a signed long and see if it works.
523 */
524
525 result = PyLong_AsLongAndOverflow(index, &overflow);
526
527 if (!overflow) {
528 uid = (uid_t)result;
529
530 if (result == -1) {
531 if (PyErr_Occurred())
532 goto fail;
533 /* It's a legitimate -1, we're done. */
534 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200535 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700536
537 /* Any other negative number is disallowed. */
538 if (result < 0)
539 goto underflow;
540
541 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200542 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700543 (long)uid != result)
544 goto underflow;
545 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200546 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700547
548 if (overflow < 0)
549 goto underflow;
550
551 /*
552 * Okay, the value overflowed a signed long. If it
553 * fits in an *unsigned* long, it may still be okay,
554 * as uid_t may be unsigned long on this platform.
555 */
556 uresult = PyLong_AsUnsignedLong(index);
557 if (PyErr_Occurred()) {
558 if (PyErr_ExceptionMatches(PyExc_OverflowError))
559 goto overflow;
560 goto fail;
561 }
562
563 uid = (uid_t)uresult;
564
565 /*
566 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
567 * but this value would get interpreted as (uid_t)-1 by chown
568 * and its siblings. That's not what the user meant! So we
569 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100570 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700571 */
572 if (uid == (uid_t)-1)
573 goto overflow;
574
575 /* Ensure the value wasn't truncated. */
576 if (sizeof(uid_t) < sizeof(long) &&
577 (unsigned long)uid != uresult)
578 goto overflow;
579 /* fallthrough */
580
581success:
582 Py_DECREF(index);
583 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200584 return 1;
585
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700586underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200587 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700588 "uid is less than minimum");
589 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200590
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700591overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200592 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700593 "uid is greater than maximum");
594 /* fallthrough */
595
596fail:
597 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200598 return 0;
599}
600
601int
602_Py_Gid_Converter(PyObject *obj, void *p)
603{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700604 gid_t gid;
605 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200606 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200607 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700608 unsigned long uresult;
609
610 index = PyNumber_Index(obj);
611 if (index == NULL) {
612 PyErr_Format(PyExc_TypeError,
613 "gid should be integer, not %.200s",
614 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200615 return 0;
616 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700617
618 /*
619 * Handling gid_t is complicated for two reasons:
620 * * Although gid_t is (always?) unsigned, it still
621 * accepts -1.
622 * * We don't know its size in advance--it may be
623 * bigger than an int, or it may be smaller than
624 * a long.
625 *
626 * So a bit of defensive programming is in order.
627 * Start with interpreting the value passed
628 * in as a signed long and see if it works.
629 */
630
631 result = PyLong_AsLongAndOverflow(index, &overflow);
632
633 if (!overflow) {
634 gid = (gid_t)result;
635
636 if (result == -1) {
637 if (PyErr_Occurred())
638 goto fail;
639 /* It's a legitimate -1, we're done. */
640 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200641 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700642
643 /* Any other negative number is disallowed. */
644 if (result < 0) {
645 goto underflow;
646 }
647
648 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200649 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700650 (long)gid != result)
651 goto underflow;
652 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200653 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700654
655 if (overflow < 0)
656 goto underflow;
657
658 /*
659 * Okay, the value overflowed a signed long. If it
660 * fits in an *unsigned* long, it may still be okay,
661 * as gid_t may be unsigned long on this platform.
662 */
663 uresult = PyLong_AsUnsignedLong(index);
664 if (PyErr_Occurred()) {
665 if (PyErr_ExceptionMatches(PyExc_OverflowError))
666 goto overflow;
667 goto fail;
668 }
669
670 gid = (gid_t)uresult;
671
672 /*
673 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
674 * but this value would get interpreted as (gid_t)-1 by chown
675 * and its siblings. That's not what the user meant! So we
676 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100677 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700678 */
679 if (gid == (gid_t)-1)
680 goto overflow;
681
682 /* Ensure the value wasn't truncated. */
683 if (sizeof(gid_t) < sizeof(long) &&
684 (unsigned long)gid != uresult)
685 goto overflow;
686 /* fallthrough */
687
688success:
689 Py_DECREF(index);
690 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200691 return 1;
692
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700693underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200694 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700695 "gid is less than minimum");
696 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200697
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700698overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200699 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700700 "gid is greater than maximum");
701 /* fallthrough */
702
703fail:
704 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200705 return 0;
706}
707#endif /* MS_WINDOWS */
708
709
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700710#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800711
712
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200713#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
714static int
715_Py_Dev_Converter(PyObject *obj, void *p)
716{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200717 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200718 if (PyErr_Occurred())
719 return 0;
720 return 1;
721}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800722#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200723
724
Larry Hastings9cf065c2012-06-22 16:30:09 -0700725#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400726/*
727 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
728 * without the int cast, the value gets interpreted as uint (4291925331),
729 * which doesn't play nicely with all the initializer lines in this file that
730 * look like this:
731 * int dir_fd = DEFAULT_DIR_FD;
732 */
733#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700734#else
735#define DEFAULT_DIR_FD (-100)
736#endif
737
738static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300739_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200740{
741 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700742 long long_value;
743
744 PyObject *index = PyNumber_Index(o);
745 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700746 return 0;
747 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700748
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300749 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700750 long_value = PyLong_AsLongAndOverflow(index, &overflow);
751 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300752 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200753 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700754 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700755 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700756 return 0;
757 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200758 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700759 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700760 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700761 return 0;
762 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700763
Larry Hastings9cf065c2012-06-22 16:30:09 -0700764 *p = (int)long_value;
765 return 1;
766}
767
768static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200769dir_fd_converter(PyObject *o, void *p)
770{
771 if (o == Py_None) {
772 *(int *)p = DEFAULT_DIR_FD;
773 return 1;
774 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300775 else if (PyIndex_Check(o)) {
776 return _fd_converter(o, (int *)p);
777 }
778 else {
779 PyErr_Format(PyExc_TypeError,
780 "argument should be integer or None, not %.200s",
781 Py_TYPE(o)->tp_name);
782 return 0;
783 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784}
785
786
Larry Hastings9cf065c2012-06-22 16:30:09 -0700787/*
788 * A PyArg_ParseTuple "converter" function
789 * that handles filesystem paths in the manner
790 * preferred by the os module.
791 *
792 * path_converter accepts (Unicode) strings and their
793 * subclasses, and bytes and their subclasses. What
794 * it does with the argument depends on the platform:
795 *
796 * * On Windows, if we get a (Unicode) string we
797 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700798 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700799 *
800 * * On all other platforms, strings are encoded
801 * to bytes using PyUnicode_FSConverter, then we
802 * extract the char * from the bytes object and
803 * return that.
804 *
805 * path_converter also optionally accepts signed
806 * integers (representing open file descriptors) instead
807 * of path strings.
808 *
809 * Input fields:
810 * path.nullable
811 * If nonzero, the path is permitted to be None.
812 * path.allow_fd
813 * If nonzero, the path is permitted to be a file handle
814 * (a signed int) instead of a string.
815 * path.function_name
816 * If non-NULL, path_converter will use that as the name
817 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700818 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700819 * path.argument_name
820 * If non-NULL, path_converter will use that as the name
821 * of the parameter in error messages.
822 * (If path.argument_name is NULL it uses "path".)
823 *
824 * Output fields:
825 * path.wide
826 * Points to the path if it was expressed as Unicode
827 * and was not encoded. (Only used on Windows.)
828 * path.narrow
829 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700830 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000831 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700832 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700833 * path.fd
834 * Contains a file descriptor if path.accept_fd was true
835 * and the caller provided a signed integer instead of any
836 * sort of string.
837 *
838 * WARNING: if your "path" parameter is optional, and is
839 * unspecified, path_converter will never get called.
840 * So if you set allow_fd, you *MUST* initialize path.fd = -1
841 * yourself!
842 * path.length
843 * The length of the path in characters, if specified as
844 * a string.
845 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800846 * The original object passed in (if get a PathLike object,
847 * the result of PyOS_FSPath() is treated as the original object).
848 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700849 * path.cleanup
850 * For internal use only. May point to a temporary object.
851 * (Pay no attention to the man behind the curtain.)
852 *
853 * At most one of path.wide or path.narrow will be non-NULL.
854 * If path was None and path.nullable was set,
855 * or if path was an integer and path.allow_fd was set,
856 * both path.wide and path.narrow will be NULL
857 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200858 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700859 * path_converter takes care to not write to the path_t
860 * unless it's successful. However it must reset the
861 * "cleanup" field each time it's called.
862 *
863 * Use as follows:
864 * path_t path;
865 * memset(&path, 0, sizeof(path));
866 * PyArg_ParseTuple(args, "O&", path_converter, &path);
867 * // ... use values from path ...
868 * path_cleanup(&path);
869 *
870 * (Note that if PyArg_Parse fails you don't need to call
871 * path_cleanup(). However it is safe to do so.)
872 */
873typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100874 const char *function_name;
875 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700876 int nullable;
877 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300878 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700879#ifdef MS_WINDOWS
880 BOOL narrow;
881#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300882 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700883#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700884 int fd;
885 Py_ssize_t length;
886 PyObject *object;
887 PyObject *cleanup;
888} path_t;
889
Steve Dowercc16be82016-09-08 10:35:16 -0700890#ifdef MS_WINDOWS
891#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
892 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
893#else
Larry Hastings2f936352014-08-05 14:04:04 +1000894#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
895 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700896#endif
Larry Hastings31826802013-10-19 00:09:25 -0700897
Larry Hastings9cf065c2012-06-22 16:30:09 -0700898static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800899path_cleanup(path_t *path)
900{
901 Py_CLEAR(path->object);
902 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700903}
904
905static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300906path_converter(PyObject *o, void *p)
907{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700908 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800909 PyObject *bytes = NULL;
910 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700911 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300912 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700913#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800914 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700915 const wchar_t *wide;
916#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700917
918#define FORMAT_EXCEPTION(exc, fmt) \
919 PyErr_Format(exc, "%s%s" fmt, \
920 path->function_name ? path->function_name : "", \
921 path->function_name ? ": " : "", \
922 path->argument_name ? path->argument_name : "path")
923
924 /* Py_CLEANUP_SUPPORTED support */
925 if (o == NULL) {
926 path_cleanup(path);
927 return 1;
928 }
929
Brett Cannon3f9183b2016-08-26 14:44:48 -0700930 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800931 path->object = path->cleanup = NULL;
932 /* path->object owns a reference to the original object */
933 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700934
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300935 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700936 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700937#ifdef MS_WINDOWS
938 path->narrow = FALSE;
939#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700940 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700941#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700942 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800943 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700944 }
945
Brett Cannon3f9183b2016-08-26 14:44:48 -0700946 /* Only call this here so that we don't treat the return value of
947 os.fspath() as an fd or buffer. */
948 is_index = path->allow_fd && PyIndex_Check(o);
949 is_buffer = PyObject_CheckBuffer(o);
950 is_bytes = PyBytes_Check(o);
951 is_unicode = PyUnicode_Check(o);
952
953 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
954 /* Inline PyOS_FSPath() for better error messages. */
955 _Py_IDENTIFIER(__fspath__);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000956 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700957
958 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
959 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800960 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700961 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000962 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700963 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000964 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700965 goto error_exit;
966 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000967 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700968 is_unicode = 1;
969 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000970 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700971 is_bytes = 1;
972 }
973 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000974 PyErr_Format(PyExc_TypeError,
975 "expected %.200s.__fspath__() to return str or bytes, "
976 "not %.200s", Py_TYPE(o)->tp_name,
977 Py_TYPE(res)->tp_name);
978 Py_DECREF(res);
979 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700980 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +0000981
982 /* still owns a reference to the original object */
983 Py_DECREF(o);
984 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700985 }
986
987 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700988#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +0200989 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100990 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800991 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700992 }
Victor Stinner59799a82013-11-13 14:17:30 +0100993 if (length > 32767) {
994 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +0800995 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700996 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300997 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300998 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +0800999 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001000 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001
1002 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001003 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001004 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001005 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001006#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001007 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001008 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001009 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001010#endif
1011 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001012 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001013 bytes = o;
1014 Py_INCREF(bytes);
1015 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001016 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001017 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001018 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001019 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1020 "%s%s%s should be %s, not %.200s",
1021 path->function_name ? path->function_name : "",
1022 path->function_name ? ": " : "",
1023 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001024 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1025 "integer or None" :
1026 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1027 path->nullable ? "string, bytes, os.PathLike or None" :
1028 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001029 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001030 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001031 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001032 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001033 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001034 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001035 }
1036 }
Steve Dowercc16be82016-09-08 10:35:16 -07001037 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001038 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001039 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001040 }
1041 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001042#ifdef MS_WINDOWS
1043 path->narrow = FALSE;
1044#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001045 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001046#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001047 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001048 }
1049 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001050 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001051 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1052 path->function_name ? path->function_name : "",
1053 path->function_name ? ": " : "",
1054 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001055 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1056 "integer or None" :
1057 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1058 path->nullable ? "string, bytes, os.PathLike or None" :
1059 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001060 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001061 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001062 }
1063
Larry Hastings9cf065c2012-06-22 16:30:09 -07001064 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001065 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001066 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001067 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001068 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001069 }
1070
Steve Dowercc16be82016-09-08 10:35:16 -07001071#ifdef MS_WINDOWS
1072 wo = PyUnicode_DecodeFSDefaultAndSize(
1073 narrow,
1074 length
1075 );
1076 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001077 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001078 }
1079
Xiang Zhang04316c42017-01-08 23:26:57 +08001080 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001081 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001082 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001083 }
1084 if (length > 32767) {
1085 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001086 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001087 }
1088 if (wcslen(wide) != length) {
1089 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001090 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001091 }
1092 path->wide = wide;
1093 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001094 path->cleanup = wo;
1095 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001096#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001097 path->wide = NULL;
1098 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001099 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001100 /* Still a reference owned by path->object, don't have to
1101 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001102 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001103 }
1104 else {
1105 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001106 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001107#endif
1108 path->fd = -1;
1109
1110 success_exit:
1111 path->length = length;
1112 path->object = o;
1113 return Py_CLEANUP_SUPPORTED;
1114
1115 error_exit:
1116 Py_XDECREF(o);
1117 Py_XDECREF(bytes);
1118#ifdef MS_WINDOWS
1119 Py_XDECREF(wo);
1120#endif
1121 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001122}
1123
1124static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001125argument_unavailable_error(const char *function_name, const char *argument_name)
1126{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001127 PyErr_Format(PyExc_NotImplementedError,
1128 "%s%s%s unavailable on this platform",
1129 (function_name != NULL) ? function_name : "",
1130 (function_name != NULL) ? ": ": "",
1131 argument_name);
1132}
1133
1134static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001135dir_fd_unavailable(PyObject *o, void *p)
1136{
1137 int dir_fd;
1138 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001139 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001140 if (dir_fd != DEFAULT_DIR_FD) {
1141 argument_unavailable_error(NULL, "dir_fd");
1142 return 0;
1143 }
1144 *(int *)p = dir_fd;
1145 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001146}
1147
1148static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001149fd_specified(const char *function_name, int fd)
1150{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001151 if (fd == -1)
1152 return 0;
1153
1154 argument_unavailable_error(function_name, "fd");
1155 return 1;
1156}
1157
1158static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001159follow_symlinks_specified(const char *function_name, int follow_symlinks)
1160{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001161 if (follow_symlinks)
1162 return 0;
1163
1164 argument_unavailable_error(function_name, "follow_symlinks");
1165 return 1;
1166}
1167
1168static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001169path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1170{
Steve Dowercc16be82016-09-08 10:35:16 -07001171 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1172#ifndef MS_WINDOWS
1173 && !path->narrow
1174#endif
1175 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001176 PyErr_Format(PyExc_ValueError,
1177 "%s: can't specify dir_fd without matching path",
1178 function_name);
1179 return 1;
1180 }
1181 return 0;
1182}
1183
1184static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001185dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1186{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001187 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1188 PyErr_Format(PyExc_ValueError,
1189 "%s: can't specify both dir_fd and fd",
1190 function_name);
1191 return 1;
1192 }
1193 return 0;
1194}
1195
1196static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001197fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1198 int follow_symlinks)
1199{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001200 if ((fd > 0) && (!follow_symlinks)) {
1201 PyErr_Format(PyExc_ValueError,
1202 "%s: cannot use fd and follow_symlinks together",
1203 function_name);
1204 return 1;
1205 }
1206 return 0;
1207}
1208
1209static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001210dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1211 int follow_symlinks)
1212{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001213 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1214 PyErr_Format(PyExc_ValueError,
1215 "%s: cannot use dir_fd and follow_symlinks together",
1216 function_name);
1217 return 1;
1218 }
1219 return 0;
1220}
1221
Larry Hastings2f936352014-08-05 14:04:04 +10001222#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001223 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001224#else
Larry Hastings2f936352014-08-05 14:04:04 +10001225 typedef off_t Py_off_t;
1226#endif
1227
1228static int
1229Py_off_t_converter(PyObject *arg, void *addr)
1230{
1231#ifdef HAVE_LARGEFILE_SUPPORT
1232 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1233#else
1234 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001235#endif
1236 if (PyErr_Occurred())
1237 return 0;
1238 return 1;
1239}
Larry Hastings2f936352014-08-05 14:04:04 +10001240
1241static PyObject *
1242PyLong_FromPy_off_t(Py_off_t offset)
1243{
1244#ifdef HAVE_LARGEFILE_SUPPORT
1245 return PyLong_FromLongLong(offset);
1246#else
1247 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001248#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001249}
1250
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001251#ifdef HAVE_SIGSET_T
1252/* Convert an iterable of integers to a sigset.
1253 Return 1 on success, return 0 and raise an exception on error. */
1254int
1255_Py_Sigset_Converter(PyObject *obj, void *addr)
1256{
1257 sigset_t *mask = (sigset_t *)addr;
1258 PyObject *iterator, *item;
1259 long signum;
1260 int overflow;
1261
Rémi Lapeyref0900192019-05-04 01:30:53 +02001262 // The extra parens suppress the unreachable-code warning with clang on MacOS
1263 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001264 /* Probably only if mask == NULL. */
1265 PyErr_SetFromErrno(PyExc_OSError);
1266 return 0;
1267 }
1268
1269 iterator = PyObject_GetIter(obj);
1270 if (iterator == NULL) {
1271 return 0;
1272 }
1273
1274 while ((item = PyIter_Next(iterator)) != NULL) {
1275 signum = PyLong_AsLongAndOverflow(item, &overflow);
1276 Py_DECREF(item);
1277 if (signum <= 0 || signum >= NSIG) {
1278 if (overflow || signum != -1 || !PyErr_Occurred()) {
1279 PyErr_Format(PyExc_ValueError,
1280 "signal number %ld out of range", signum);
1281 }
1282 goto error;
1283 }
1284 if (sigaddset(mask, (int)signum)) {
1285 if (errno != EINVAL) {
1286 /* Probably impossible */
1287 PyErr_SetFromErrno(PyExc_OSError);
1288 goto error;
1289 }
1290 /* For backwards compatibility, allow idioms such as
1291 * `range(1, NSIG)` but warn about invalid signal numbers
1292 */
1293 const char msg[] =
1294 "invalid signal number %ld, please use valid_signals()";
1295 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1296 goto error;
1297 }
1298 }
1299 }
1300 if (!PyErr_Occurred()) {
1301 Py_DECREF(iterator);
1302 return 1;
1303 }
1304
1305error:
1306 Py_DECREF(iterator);
1307 return 0;
1308}
1309#endif /* HAVE_SIGSET_T */
1310
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001311#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001312
1313static int
Brian Curtind25aef52011-06-13 15:16:04 -05001314win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001315{
Martin Panter70214ad2016-08-04 02:38:59 +00001316 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1317 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001318 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001319
1320 if (0 == DeviceIoControl(
1321 reparse_point_handle,
1322 FSCTL_GET_REPARSE_POINT,
1323 NULL, 0, /* in buffer */
1324 target_buffer, sizeof(target_buffer),
1325 &n_bytes_returned,
1326 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001327 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001328
1329 if (reparse_tag)
1330 *reparse_tag = rdb->ReparseTag;
1331
Brian Curtind25aef52011-06-13 15:16:04 -05001332 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001333}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001334
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001335#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001336
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001337/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001338#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001339/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001340** environ directly, we must obtain it with _NSGetEnviron(). See also
1341** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001342*/
1343#include <crt_externs.h>
1344static char **environ;
1345#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001347#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001348
Barry Warsaw53699e91996-12-10 23:23:01 +00001349static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001350convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001351{
Victor Stinner8c62be82010-05-06 00:08:46 +00001352 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001353#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001354 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001355#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001356 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001357#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001358
Victor Stinner8c62be82010-05-06 00:08:46 +00001359 d = PyDict_New();
1360 if (d == NULL)
1361 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001362#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 if (environ == NULL)
1364 environ = *_NSGetEnviron();
1365#endif
1366#ifdef MS_WINDOWS
1367 /* _wenviron must be initialized in this way if the program is started
1368 through main() instead of wmain(). */
1369 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001370 e = _wenviron;
Victor Stinner8c62be82010-05-06 00:08:46 +00001371#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001372 e = environ;
1373#endif
1374 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001375 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001376 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 PyObject *k;
1378 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001379#ifdef MS_WINDOWS
1380 const wchar_t *p = wcschr(*e, L'=');
1381#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001382 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001383#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001384 if (p == NULL)
1385 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001386#ifdef MS_WINDOWS
1387 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1388#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001389 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001390#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001391 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001392 Py_DECREF(d);
1393 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001394 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001395#ifdef MS_WINDOWS
1396 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1397#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001398 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001399#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001401 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001402 Py_DECREF(d);
1403 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001404 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001405 if (PyDict_GetItemWithError(d, k) == NULL) {
1406 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1407 Py_DECREF(v);
1408 Py_DECREF(k);
1409 Py_DECREF(d);
1410 return NULL;
1411 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001412 }
1413 Py_DECREF(k);
1414 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001415 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001416 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001417}
1418
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001419/* Set a POSIX-specific error from errno, and return NULL */
1420
Barry Warsawd58d7641998-07-23 16:14:40 +00001421static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001422posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001423{
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001425}
Mark Hammondef8b6542001-05-13 08:04:26 +00001426
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001427#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001428static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001429win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001430{
Victor Stinner8c62be82010-05-06 00:08:46 +00001431 /* XXX We should pass the function name along in the future.
1432 (winreg.c also wants to pass the function name.)
1433 This would however require an additional param to the
1434 Windows error object, which is non-trivial.
1435 */
1436 errno = GetLastError();
1437 if (filename)
1438 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1439 else
1440 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001441}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001442
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001443static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001444win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001445{
1446 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001447 if (filename)
1448 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001449 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001450 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001451 filename);
1452 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001453 return PyErr_SetFromWindowsErr(err);
1454}
1455
1456static PyObject *
1457win32_error_object(const char* function, PyObject* filename)
1458{
1459 errno = GetLastError();
1460 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001461}
1462
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001463#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001464
Larry Hastings9cf065c2012-06-22 16:30:09 -07001465static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001466posix_path_object_error(PyObject *path)
1467{
1468 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1469}
1470
1471static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001472path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001473{
1474#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001475 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1476 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001477#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001478 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001479#endif
1480}
1481
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001482static PyObject *
1483path_object_error2(PyObject *path, PyObject *path2)
1484{
1485#ifdef MS_WINDOWS
1486 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1487 PyExc_OSError, 0, path, path2);
1488#else
1489 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1490#endif
1491}
1492
1493static PyObject *
1494path_error(path_t *path)
1495{
1496 return path_object_error(path->object);
1497}
Larry Hastings31826802013-10-19 00:09:25 -07001498
Larry Hastingsb0827312014-02-09 22:05:19 -08001499static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001500posix_path_error(path_t *path)
1501{
1502 return posix_path_object_error(path->object);
1503}
1504
1505static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001506path_error2(path_t *path, path_t *path2)
1507{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001508 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001509}
1510
1511
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001512/* POSIX generic methods */
1513
Larry Hastings2f936352014-08-05 14:04:04 +10001514static int
1515fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001516{
Victor Stinner8c62be82010-05-06 00:08:46 +00001517 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001518 int *pointer = (int *)p;
1519 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001520 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001521 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001522 *pointer = fd;
1523 return 1;
1524}
1525
1526static PyObject *
1527posix_fildes_fd(int fd, int (*func)(int))
1528{
1529 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001530 int async_err = 0;
1531
1532 do {
1533 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001534 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001535 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001536 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001537 Py_END_ALLOW_THREADS
1538 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1539 if (res != 0)
1540 return (!async_err) ? posix_error() : NULL;
1541 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001542}
Guido van Rossum21142a01999-01-08 21:05:37 +00001543
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001544
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001545#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001546/* This is a reimplementation of the C library's chdir function,
1547 but one that produces Win32 errors instead of DOS error codes.
1548 chdir is essentially a wrapper around SetCurrentDirectory; however,
1549 it also needs to set "magic" environment variables indicating
1550 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001551static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001552win32_wchdir(LPCWSTR path)
1553{
Victor Stinnered537822015-12-13 21:40:26 +01001554 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001555 int result;
1556 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001557
Victor Stinner8c62be82010-05-06 00:08:46 +00001558 if(!SetCurrentDirectoryW(path))
1559 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001560 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001561 if (!result)
1562 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001563 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001564 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 if (!new_path) {
1566 SetLastError(ERROR_OUTOFMEMORY);
1567 return FALSE;
1568 }
1569 result = GetCurrentDirectoryW(result, new_path);
1570 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001571 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001572 return FALSE;
1573 }
1574 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001575 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1576 wcsncmp(new_path, L"//", 2) == 0);
1577 if (!is_unc_like_path) {
1578 env[1] = new_path[0];
1579 result = SetEnvironmentVariableW(env, new_path);
1580 }
Victor Stinnered537822015-12-13 21:40:26 +01001581 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001582 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001583 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001584}
1585#endif
1586
Martin v. Löwis14694662006-02-03 12:54:16 +00001587#ifdef MS_WINDOWS
1588/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1589 - time stamps are restricted to second resolution
1590 - file modification times suffer from forth-and-back conversions between
1591 UTC and local time
1592 Therefore, we implement our own stat, based on the Win32 API directly.
1593*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001594#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001595#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001596
Victor Stinner6036e442015-03-08 01:58:04 +01001597static void
Steve Dowercc16be82016-09-08 10:35:16 -07001598find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1599 BY_HANDLE_FILE_INFORMATION *info,
1600 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001601{
1602 memset(info, 0, sizeof(*info));
1603 info->dwFileAttributes = pFileData->dwFileAttributes;
1604 info->ftCreationTime = pFileData->ftCreationTime;
1605 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1606 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1607 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1608 info->nFileSizeLow = pFileData->nFileSizeLow;
1609/* info->nNumberOfLinks = 1; */
1610 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1611 *reparse_tag = pFileData->dwReserved0;
1612 else
1613 *reparse_tag = 0;
1614}
1615
Guido van Rossumd8faa362007-04-27 19:54:29 +00001616static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001617attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001618{
Victor Stinner8c62be82010-05-06 00:08:46 +00001619 HANDLE hFindFile;
1620 WIN32_FIND_DATAW FileData;
1621 hFindFile = FindFirstFileW(pszFile, &FileData);
1622 if (hFindFile == INVALID_HANDLE_VALUE)
1623 return FALSE;
1624 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001625 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001626 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001627}
1628
Brian Curtind25aef52011-06-13 15:16:04 -05001629static BOOL
1630get_target_path(HANDLE hdl, wchar_t **target_path)
1631{
1632 int buf_size, result_length;
1633 wchar_t *buf;
1634
1635 /* We have a good handle to the target, use it to determine
1636 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001637 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1638 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001639 if(!buf_size)
1640 return FALSE;
1641
Victor Stinnerc36674a2016-03-16 14:30:16 +01001642 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001643 if (!buf) {
1644 SetLastError(ERROR_OUTOFMEMORY);
1645 return FALSE;
1646 }
1647
Steve Dower2ea51c92015-03-20 21:49:12 -07001648 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001649 buf, buf_size, VOLUME_NAME_DOS);
1650
1651 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001652 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001653 return FALSE;
1654 }
1655
Brian Curtind25aef52011-06-13 15:16:04 -05001656 buf[result_length] = 0;
1657
1658 *target_path = buf;
1659 return TRUE;
1660}
1661
1662static int
Steve Dowercc16be82016-09-08 10:35:16 -07001663win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001664 BOOL traverse)
1665{
Victor Stinner26de69d2011-06-17 15:15:38 +02001666 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001667 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001668 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001669 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001670 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001671 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001672
Steve Dowercc16be82016-09-08 10:35:16 -07001673 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001674 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001675 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001676 0, /* share mode */
1677 NULL, /* security attributes */
1678 OPEN_EXISTING,
1679 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001680 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1681 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001682 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001683 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1684 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001685 NULL);
1686
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001687 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001688 /* Either the target doesn't exist, or we don't have access to
1689 get a handle to it. If the former, we need to return an error.
1690 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001691 DWORD lastError = GetLastError();
1692 if (lastError != ERROR_ACCESS_DENIED &&
1693 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001694 return -1;
1695 /* Could not get attributes on open file. Fall back to
1696 reading the directory. */
1697 if (!attributes_from_dir(path, &info, &reparse_tag))
1698 /* Very strange. This should not fail now */
1699 return -1;
1700 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1701 if (traverse) {
1702 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001703 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001704 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001706 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001707 } else {
1708 if (!GetFileInformationByHandle(hFile, &info)) {
1709 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001710 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001711 }
1712 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Mark Becwarb82bfac2019-02-02 16:08:23 -05001713 if (!win32_get_reparse_tag(hFile, &reparse_tag)) {
1714 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001715 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001716 }
Brian Curtind25aef52011-06-13 15:16:04 -05001717 /* Close the outer open file handle now that we're about to
1718 reopen it with different flags. */
1719 if (!CloseHandle(hFile))
1720 return -1;
1721
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001722 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001723 /* In order to call GetFinalPathNameByHandle we need to open
1724 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001725 hFile2 = CreateFileW(
1726 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1727 NULL, OPEN_EXISTING,
1728 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1729 NULL);
1730 if (hFile2 == INVALID_HANDLE_VALUE)
1731 return -1;
1732
Mark Becwarb82bfac2019-02-02 16:08:23 -05001733 if (!get_target_path(hFile2, &target_path)) {
1734 CloseHandle(hFile2);
Brian Curtind25aef52011-06-13 15:16:04 -05001735 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001736 }
1737
1738 if (!CloseHandle(hFile2)) {
1739 return -1;
1740 }
Brian Curtind25aef52011-06-13 15:16:04 -05001741
Steve Dowercc16be82016-09-08 10:35:16 -07001742 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001743 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001744 return code;
1745 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001746 } else
1747 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001748 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001749 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001750
1751 /* Set S_IEXEC if it is an .exe, .bat, ... */
1752 dot = wcsrchr(path, '.');
1753 if (dot) {
1754 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1755 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1756 result->st_mode |= 0111;
1757 }
1758 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001759}
1760
1761static int
Steve Dowercc16be82016-09-08 10:35:16 -07001762win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001763{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001764 /* Protocol violation: we explicitly clear errno, instead of
1765 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001766 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001767 errno = 0;
1768 return code;
1769}
Brian Curtind25aef52011-06-13 15:16:04 -05001770/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001771
1772 In Posix, stat automatically traverses symlinks and returns the stat
1773 structure for the target. In Windows, the equivalent GetFileAttributes by
1774 default does not traverse symlinks and instead returns attributes for
1775 the symlink.
1776
1777 Therefore, win32_lstat will get the attributes traditionally, and
1778 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001779 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001780
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001781static int
Steve Dowercc16be82016-09-08 10:35:16 -07001782win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001783{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001784 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001785}
1786
Victor Stinner8c62be82010-05-06 00:08:46 +00001787static int
Steve Dowercc16be82016-09-08 10:35:16 -07001788win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001789{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001790 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001791}
1792
Martin v. Löwis14694662006-02-03 12:54:16 +00001793#endif /* MS_WINDOWS */
1794
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001795PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001796"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001797This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001798 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001799or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1800\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001801Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1802or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001803\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001804See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001805
1806static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001807 {"st_mode", "protection bits"},
1808 {"st_ino", "inode"},
1809 {"st_dev", "device"},
1810 {"st_nlink", "number of hard links"},
1811 {"st_uid", "user ID of owner"},
1812 {"st_gid", "group ID of owner"},
1813 {"st_size", "total size, in bytes"},
1814 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1815 {NULL, "integer time of last access"},
1816 {NULL, "integer time of last modification"},
1817 {NULL, "integer time of last change"},
1818 {"st_atime", "time of last access"},
1819 {"st_mtime", "time of last modification"},
1820 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001821 {"st_atime_ns", "time of last access in nanoseconds"},
1822 {"st_mtime_ns", "time of last modification in nanoseconds"},
1823 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001824#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001825 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001826#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001827#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001829#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001830#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001831 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001832#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001833#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001834 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001835#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001836#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001837 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001838#endif
1839#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001840 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001841#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001842#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1843 {"st_file_attributes", "Windows file attribute bits"},
1844#endif
jcea6c51d512018-01-28 14:00:08 +01001845#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1846 {"st_fstype", "Type of filesystem"},
1847#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001848 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001849};
1850
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001851#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001852#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001853#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001854#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001855#endif
1856
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001857#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001858#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1859#else
1860#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1861#endif
1862
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001863#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001864#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1865#else
1866#define ST_RDEV_IDX ST_BLOCKS_IDX
1867#endif
1868
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001869#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1870#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1871#else
1872#define ST_FLAGS_IDX ST_RDEV_IDX
1873#endif
1874
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001875#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001876#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001877#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001878#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001879#endif
1880
1881#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1882#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1883#else
1884#define ST_BIRTHTIME_IDX ST_GEN_IDX
1885#endif
1886
Zachary Ware63f277b2014-06-19 09:46:37 -05001887#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1888#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1889#else
1890#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1891#endif
1892
jcea6c51d512018-01-28 14:00:08 +01001893#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1894#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1895#else
1896#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1897#endif
1898
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001899static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001900 "stat_result", /* name */
1901 stat_result__doc__, /* doc */
1902 stat_result_fields,
1903 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001904};
1905
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001906PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001907"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1908This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001909 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001910or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001911\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001912See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001913
1914static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001915 {"f_bsize", },
1916 {"f_frsize", },
1917 {"f_blocks", },
1918 {"f_bfree", },
1919 {"f_bavail", },
1920 {"f_files", },
1921 {"f_ffree", },
1922 {"f_favail", },
1923 {"f_flag", },
1924 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001925 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001926 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001927};
1928
1929static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001930 "statvfs_result", /* name */
1931 statvfs_result__doc__, /* doc */
1932 statvfs_result_fields,
1933 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001934};
1935
Ross Lagerwall7807c352011-03-17 20:20:30 +02001936#if defined(HAVE_WAITID) && !defined(__APPLE__)
1937PyDoc_STRVAR(waitid_result__doc__,
1938"waitid_result: Result from waitid.\n\n\
1939This object may be accessed either as a tuple of\n\
1940 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1941or via the attributes si_pid, si_uid, and so on.\n\
1942\n\
1943See os.waitid for more information.");
1944
1945static PyStructSequence_Field waitid_result_fields[] = {
1946 {"si_pid", },
1947 {"si_uid", },
1948 {"si_signo", },
1949 {"si_status", },
1950 {"si_code", },
1951 {0}
1952};
1953
1954static PyStructSequence_Desc waitid_result_desc = {
1955 "waitid_result", /* name */
1956 waitid_result__doc__, /* doc */
1957 waitid_result_fields,
1958 5
1959};
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001960static PyTypeObject* WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +02001961#endif
1962
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001963static int initialized;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001964static PyTypeObject* StatResultType;
1965static PyTypeObject* StatVFSResultType;
William Orr81574b82018-10-01 22:19:56 -07001966#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001967static PyTypeObject* SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001968#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001969static newfunc structseq_new;
1970
1971static PyObject *
1972statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1973{
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 PyStructSequence *result;
1975 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001976
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 result = (PyStructSequence*)structseq_new(type, args, kwds);
1978 if (!result)
1979 return NULL;
1980 /* If we have been initialized from a tuple,
1981 st_?time might be set to None. Initialize it
1982 from the int slots. */
1983 for (i = 7; i <= 9; i++) {
1984 if (result->ob_item[i+3] == Py_None) {
1985 Py_DECREF(Py_None);
1986 Py_INCREF(result->ob_item[i]);
1987 result->ob_item[i+3] = result->ob_item[i];
1988 }
1989 }
1990 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001991}
1992
1993
Larry Hastings6fe20b32012-04-19 15:07:49 -07001994static PyObject *billion = NULL;
1995
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001996static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001997fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001998{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001999 PyObject *s = _PyLong_FromTime_t(sec);
2000 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2001 PyObject *s_in_ns = NULL;
2002 PyObject *ns_total = NULL;
2003 PyObject *float_s = NULL;
2004
2005 if (!(s && ns_fractional))
2006 goto exit;
2007
2008 s_in_ns = PyNumber_Multiply(s, billion);
2009 if (!s_in_ns)
2010 goto exit;
2011
2012 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2013 if (!ns_total)
2014 goto exit;
2015
Victor Stinner01b5aab2017-10-24 02:02:00 -07002016 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2017 if (!float_s) {
2018 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002019 }
2020
2021 PyStructSequence_SET_ITEM(v, index, s);
2022 PyStructSequence_SET_ITEM(v, index+3, float_s);
2023 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2024 s = NULL;
2025 float_s = NULL;
2026 ns_total = NULL;
2027exit:
2028 Py_XDECREF(s);
2029 Py_XDECREF(ns_fractional);
2030 Py_XDECREF(s_in_ns);
2031 Py_XDECREF(ns_total);
2032 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002033}
2034
Tim Peters5aa91602002-01-30 05:46:57 +00002035/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002036 (used by posix_stat() and posix_fstat()) */
2037static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002038_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002039{
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 unsigned long ansec, mnsec, cnsec;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002041 PyObject *v = PyStructSequence_New(StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002042 if (v == NULL)
2043 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002044
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002046 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002047 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002048#ifdef MS_WINDOWS
2049 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002050#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002051 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002052#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002054#if defined(MS_WINDOWS)
2055 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2056 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2057#else
2058 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2059 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2060#endif
xdegaye50e86032017-05-22 11:15:08 +02002061 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2062 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002063
Martin v. Löwis14694662006-02-03 12:54:16 +00002064#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 ansec = st->st_atim.tv_nsec;
2066 mnsec = st->st_mtim.tv_nsec;
2067 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002068#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 ansec = st->st_atimespec.tv_nsec;
2070 mnsec = st->st_mtimespec.tv_nsec;
2071 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002072#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002073 ansec = st->st_atime_nsec;
2074 mnsec = st->st_mtime_nsec;
2075 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002076#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002078#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002079 fill_time(v, 7, st->st_atime, ansec);
2080 fill_time(v, 8, st->st_mtime, mnsec);
2081 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002082
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002083#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2085 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002086#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002087#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002088 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2089 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002090#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002091#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002092 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2093 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002094#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002095#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002096 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2097 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002098#endif
2099#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002101 PyObject *val;
2102 unsigned long bsec,bnsec;
2103 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002104#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002105 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002106#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002107 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002108#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002109 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002110 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2111 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002112 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002113#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002114#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002115 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2116 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002117#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002118#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2119 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2120 PyLong_FromUnsignedLong(st->st_file_attributes));
2121#endif
jcea6c51d512018-01-28 14:00:08 +01002122#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2123 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2124 PyUnicode_FromString(st->st_fstype));
2125#endif
Fred Drake699f3522000-06-29 21:12:41 +00002126
Victor Stinner8c62be82010-05-06 00:08:46 +00002127 if (PyErr_Occurred()) {
2128 Py_DECREF(v);
2129 return NULL;
2130 }
Fred Drake699f3522000-06-29 21:12:41 +00002131
Victor Stinner8c62be82010-05-06 00:08:46 +00002132 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002133}
2134
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002135/* POSIX methods */
2136
Guido van Rossum94f6f721999-01-06 18:42:14 +00002137
2138static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002139posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002140 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002141{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002142 STRUCT_STAT st;
2143 int result;
2144
2145#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2146 if (follow_symlinks_specified(function_name, follow_symlinks))
2147 return NULL;
2148#endif
2149
2150 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2151 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2152 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2153 return NULL;
2154
2155 Py_BEGIN_ALLOW_THREADS
2156 if (path->fd != -1)
2157 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002158#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002159 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002160 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002161 else
Steve Dowercc16be82016-09-08 10:35:16 -07002162 result = win32_lstat(path->wide, &st);
2163#else
2164 else
2165#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002166 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2167 result = LSTAT(path->narrow, &st);
2168 else
Steve Dowercc16be82016-09-08 10:35:16 -07002169#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002170#ifdef HAVE_FSTATAT
2171 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2172 result = fstatat(dir_fd, path->narrow, &st,
2173 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2174 else
Steve Dowercc16be82016-09-08 10:35:16 -07002175#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002176 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002177#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002178 Py_END_ALLOW_THREADS
2179
Victor Stinner292c8352012-10-30 02:17:38 +01002180 if (result != 0) {
2181 return path_error(path);
2182 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002183
2184 return _pystat_fromstructstat(&st);
2185}
2186
Larry Hastings2f936352014-08-05 14:04:04 +10002187/*[python input]
2188
2189for s in """
2190
2191FACCESSAT
2192FCHMODAT
2193FCHOWNAT
2194FSTATAT
2195LINKAT
2196MKDIRAT
2197MKFIFOAT
2198MKNODAT
2199OPENAT
2200READLINKAT
2201SYMLINKAT
2202UNLINKAT
2203
2204""".strip().split():
2205 s = s.strip()
2206 print("""
2207#ifdef HAVE_{s}
2208 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002209#else
Larry Hastings2f936352014-08-05 14:04:04 +10002210 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002211#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002212""".rstrip().format(s=s))
2213
2214for s in """
2215
2216FCHDIR
2217FCHMOD
2218FCHOWN
2219FDOPENDIR
2220FEXECVE
2221FPATHCONF
2222FSTATVFS
2223FTRUNCATE
2224
2225""".strip().split():
2226 s = s.strip()
2227 print("""
2228#ifdef HAVE_{s}
2229 #define PATH_HAVE_{s} 1
2230#else
2231 #define PATH_HAVE_{s} 0
2232#endif
2233
2234""".rstrip().format(s=s))
2235[python start generated code]*/
2236
2237#ifdef HAVE_FACCESSAT
2238 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2239#else
2240 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2241#endif
2242
2243#ifdef HAVE_FCHMODAT
2244 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2245#else
2246 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2247#endif
2248
2249#ifdef HAVE_FCHOWNAT
2250 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2251#else
2252 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2253#endif
2254
2255#ifdef HAVE_FSTATAT
2256 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2257#else
2258 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2259#endif
2260
2261#ifdef HAVE_LINKAT
2262 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2263#else
2264 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2265#endif
2266
2267#ifdef HAVE_MKDIRAT
2268 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2269#else
2270 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2271#endif
2272
2273#ifdef HAVE_MKFIFOAT
2274 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2275#else
2276 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2277#endif
2278
2279#ifdef HAVE_MKNODAT
2280 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2281#else
2282 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2283#endif
2284
2285#ifdef HAVE_OPENAT
2286 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2287#else
2288 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2289#endif
2290
2291#ifdef HAVE_READLINKAT
2292 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2293#else
2294 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2295#endif
2296
2297#ifdef HAVE_SYMLINKAT
2298 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2299#else
2300 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2301#endif
2302
2303#ifdef HAVE_UNLINKAT
2304 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2305#else
2306 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2307#endif
2308
2309#ifdef HAVE_FCHDIR
2310 #define PATH_HAVE_FCHDIR 1
2311#else
2312 #define PATH_HAVE_FCHDIR 0
2313#endif
2314
2315#ifdef HAVE_FCHMOD
2316 #define PATH_HAVE_FCHMOD 1
2317#else
2318 #define PATH_HAVE_FCHMOD 0
2319#endif
2320
2321#ifdef HAVE_FCHOWN
2322 #define PATH_HAVE_FCHOWN 1
2323#else
2324 #define PATH_HAVE_FCHOWN 0
2325#endif
2326
2327#ifdef HAVE_FDOPENDIR
2328 #define PATH_HAVE_FDOPENDIR 1
2329#else
2330 #define PATH_HAVE_FDOPENDIR 0
2331#endif
2332
2333#ifdef HAVE_FEXECVE
2334 #define PATH_HAVE_FEXECVE 1
2335#else
2336 #define PATH_HAVE_FEXECVE 0
2337#endif
2338
2339#ifdef HAVE_FPATHCONF
2340 #define PATH_HAVE_FPATHCONF 1
2341#else
2342 #define PATH_HAVE_FPATHCONF 0
2343#endif
2344
2345#ifdef HAVE_FSTATVFS
2346 #define PATH_HAVE_FSTATVFS 1
2347#else
2348 #define PATH_HAVE_FSTATVFS 0
2349#endif
2350
2351#ifdef HAVE_FTRUNCATE
2352 #define PATH_HAVE_FTRUNCATE 1
2353#else
2354 #define PATH_HAVE_FTRUNCATE 0
2355#endif
2356/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002357
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002358#ifdef MS_WINDOWS
2359 #undef PATH_HAVE_FTRUNCATE
2360 #define PATH_HAVE_FTRUNCATE 1
2361#endif
Larry Hastings31826802013-10-19 00:09:25 -07002362
Larry Hastings61272b72014-01-07 12:41:53 -08002363/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002364
2365class path_t_converter(CConverter):
2366
2367 type = "path_t"
2368 impl_by_reference = True
2369 parse_by_reference = True
2370
2371 converter = 'path_converter'
2372
2373 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002374 # right now path_t doesn't support default values.
2375 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002376 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002377 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002378
Larry Hastings2f936352014-08-05 14:04:04 +10002379 if self.c_default not in (None, 'Py_None'):
2380 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002381
2382 self.nullable = nullable
2383 self.allow_fd = allow_fd
2384
Larry Hastings7726ac92014-01-31 22:03:12 -08002385 def pre_render(self):
2386 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002387 if isinstance(value, str):
2388 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002389 return str(int(bool(value)))
2390
2391 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002392 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002393 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002394 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002395 strify(self.nullable),
2396 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002397 )
2398
2399 def cleanup(self):
2400 return "path_cleanup(&" + self.name + ");\n"
2401
2402
2403class dir_fd_converter(CConverter):
2404 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002405
Larry Hastings2f936352014-08-05 14:04:04 +10002406 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002407 if self.default in (unspecified, None):
2408 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002409 if isinstance(requires, str):
2410 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2411 else:
2412 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002413
Larry Hastings2f936352014-08-05 14:04:04 +10002414class fildes_converter(CConverter):
2415 type = 'int'
2416 converter = 'fildes_converter'
2417
2418class uid_t_converter(CConverter):
2419 type = "uid_t"
2420 converter = '_Py_Uid_Converter'
2421
2422class gid_t_converter(CConverter):
2423 type = "gid_t"
2424 converter = '_Py_Gid_Converter'
2425
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002426class dev_t_converter(CConverter):
2427 type = 'dev_t'
2428 converter = '_Py_Dev_Converter'
2429
2430class dev_t_return_converter(unsigned_long_return_converter):
2431 type = 'dev_t'
2432 conversion_fn = '_PyLong_FromDev'
2433 unsigned_cast = '(dev_t)'
2434
Larry Hastings2f936352014-08-05 14:04:04 +10002435class FSConverter_converter(CConverter):
2436 type = 'PyObject *'
2437 converter = 'PyUnicode_FSConverter'
2438 def converter_init(self):
2439 if self.default is not unspecified:
2440 fail("FSConverter_converter does not support default values")
2441 self.c_default = 'NULL'
2442
2443 def cleanup(self):
2444 return "Py_XDECREF(" + self.name + ");\n"
2445
2446class pid_t_converter(CConverter):
2447 type = 'pid_t'
2448 format_unit = '" _Py_PARSE_PID "'
2449
2450class idtype_t_converter(int_converter):
2451 type = 'idtype_t'
2452
2453class id_t_converter(CConverter):
2454 type = 'id_t'
2455 format_unit = '" _Py_PARSE_PID "'
2456
Benjamin Petersonca470632016-09-06 13:47:26 -07002457class intptr_t_converter(CConverter):
2458 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002459 format_unit = '" _Py_PARSE_INTPTR "'
2460
2461class Py_off_t_converter(CConverter):
2462 type = 'Py_off_t'
2463 converter = 'Py_off_t_converter'
2464
2465class Py_off_t_return_converter(long_return_converter):
2466 type = 'Py_off_t'
2467 conversion_fn = 'PyLong_FromPy_off_t'
2468
2469class path_confname_converter(CConverter):
2470 type="int"
2471 converter="conv_path_confname"
2472
2473class confstr_confname_converter(path_confname_converter):
2474 converter='conv_confstr_confname'
2475
2476class sysconf_confname_converter(path_confname_converter):
2477 converter="conv_sysconf_confname"
2478
2479class sched_param_converter(CConverter):
2480 type = 'struct sched_param'
2481 converter = 'convert_sched_param'
2482 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002483
Larry Hastings61272b72014-01-07 12:41:53 -08002484[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002485/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002486
Larry Hastings61272b72014-01-07 12:41:53 -08002487/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002488
Larry Hastings2a727912014-01-16 11:32:01 -08002489os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002490
2491 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002492 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002493 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002494
2495 *
2496
Larry Hastings2f936352014-08-05 14:04:04 +10002497 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002498 If not None, it should be a file descriptor open to a directory,
2499 and path should be a relative string; path will then be relative to
2500 that directory.
2501
2502 follow_symlinks: bool = True
2503 If False, and the last element of the path is a symbolic link,
2504 stat will examine the symbolic link itself instead of the file
2505 the link points to.
2506
2507Perform a stat system call on the given path.
2508
2509dir_fd and follow_symlinks may not be implemented
2510 on your platform. If they are unavailable, using them will raise a
2511 NotImplementedError.
2512
2513It's an error to use dir_fd or follow_symlinks when specifying path as
2514 an open file descriptor.
2515
Larry Hastings61272b72014-01-07 12:41:53 -08002516[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002517
Larry Hastings31826802013-10-19 00:09:25 -07002518static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002519os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002520/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002521{
2522 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2523}
2524
Larry Hastings2f936352014-08-05 14:04:04 +10002525
2526/*[clinic input]
2527os.lstat
2528
2529 path : path_t
2530
2531 *
2532
2533 dir_fd : dir_fd(requires='fstatat') = None
2534
2535Perform a stat system call on the given path, without following symbolic links.
2536
2537Like stat(), but do not follow symbolic links.
2538Equivalent to stat(path, follow_symlinks=False).
2539[clinic start generated code]*/
2540
Larry Hastings2f936352014-08-05 14:04:04 +10002541static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002542os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2543/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002544{
2545 int follow_symlinks = 0;
2546 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2547}
Larry Hastings31826802013-10-19 00:09:25 -07002548
Larry Hastings2f936352014-08-05 14:04:04 +10002549
Larry Hastings61272b72014-01-07 12:41:53 -08002550/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002551os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002552
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002553 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002554 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002555
2556 mode: int
2557 Operating-system mode bitfield. Can be F_OK to test existence,
2558 or the inclusive-OR of R_OK, W_OK, and X_OK.
2559
2560 *
2561
Larry Hastings2f936352014-08-05 14:04:04 +10002562 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002563 If not None, it should be a file descriptor open to a directory,
2564 and path should be relative; path will then be relative to that
2565 directory.
2566
2567 effective_ids: bool = False
2568 If True, access will use the effective uid/gid instead of
2569 the real uid/gid.
2570
2571 follow_symlinks: bool = True
2572 If False, and the last element of the path is a symbolic link,
2573 access will examine the symbolic link itself instead of the file
2574 the link points to.
2575
2576Use the real uid/gid to test for access to a path.
2577
2578{parameters}
2579dir_fd, effective_ids, and follow_symlinks may not be implemented
2580 on your platform. If they are unavailable, using them will raise a
2581 NotImplementedError.
2582
2583Note that most operations will use the effective uid/gid, therefore this
2584 routine can be used in a suid/sgid environment to test if the invoking user
2585 has the specified access to the path.
2586
Larry Hastings61272b72014-01-07 12:41:53 -08002587[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002588
Larry Hastings2f936352014-08-05 14:04:04 +10002589static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002590os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002591 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002592/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002593{
Larry Hastings2f936352014-08-05 14:04:04 +10002594 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002595
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002596#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002597 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002598#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002599 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002600#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002601
Larry Hastings9cf065c2012-06-22 16:30:09 -07002602#ifndef HAVE_FACCESSAT
2603 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002604 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605
2606 if (effective_ids) {
2607 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002608 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002609 }
2610#endif
2611
2612#ifdef MS_WINDOWS
2613 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002614 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002615 Py_END_ALLOW_THREADS
2616
2617 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002618 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002619 * * we didn't get a -1, and
2620 * * write access wasn't requested,
2621 * * or the file isn't read-only,
2622 * * or it's a directory.
2623 * (Directories cannot be read-only on Windows.)
2624 */
Larry Hastings2f936352014-08-05 14:04:04 +10002625 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002626 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002628 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002629#else
2630
2631 Py_BEGIN_ALLOW_THREADS
2632#ifdef HAVE_FACCESSAT
2633 if ((dir_fd != DEFAULT_DIR_FD) ||
2634 effective_ids ||
2635 !follow_symlinks) {
2636 int flags = 0;
2637 if (!follow_symlinks)
2638 flags |= AT_SYMLINK_NOFOLLOW;
2639 if (effective_ids)
2640 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002641 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002642 }
2643 else
2644#endif
Larry Hastings31826802013-10-19 00:09:25 -07002645 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002646 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002647 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002648#endif
2649
Larry Hastings9cf065c2012-06-22 16:30:09 -07002650 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002651}
2652
Guido van Rossumd371ff11999-01-25 16:12:23 +00002653#ifndef F_OK
2654#define F_OK 0
2655#endif
2656#ifndef R_OK
2657#define R_OK 4
2658#endif
2659#ifndef W_OK
2660#define W_OK 2
2661#endif
2662#ifndef X_OK
2663#define X_OK 1
2664#endif
2665
Larry Hastings31826802013-10-19 00:09:25 -07002666
Guido van Rossumd371ff11999-01-25 16:12:23 +00002667#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002668/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002669os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002670
2671 fd: int
2672 Integer file descriptor handle.
2673
2674 /
2675
2676Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002677[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002678
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002679static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002680os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002681/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002682{
2683 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002684
Larry Hastings31826802013-10-19 00:09:25 -07002685 ret = ttyname(fd);
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002686 if (ret == NULL) {
2687 return posix_error();
2688 }
2689 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002690}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002691#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002692
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002693#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002694/*[clinic input]
2695os.ctermid
2696
2697Return the name of the controlling terminal for this process.
2698[clinic start generated code]*/
2699
Larry Hastings2f936352014-08-05 14:04:04 +10002700static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002701os_ctermid_impl(PyObject *module)
2702/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002703{
Victor Stinner8c62be82010-05-06 00:08:46 +00002704 char *ret;
2705 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002706
Greg Wardb48bc172000-03-01 21:51:56 +00002707#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002708 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002709#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002710 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002711#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002712 if (ret == NULL)
2713 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002714 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002715}
Larry Hastings2f936352014-08-05 14:04:04 +10002716#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002717
Larry Hastings2f936352014-08-05 14:04:04 +10002718
2719/*[clinic input]
2720os.chdir
2721
2722 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2723
2724Change the current working directory to the specified path.
2725
2726path may always be specified as a string.
2727On some platforms, path may also be specified as an open file descriptor.
2728 If this functionality is unavailable, using it raises an exception.
2729[clinic start generated code]*/
2730
Larry Hastings2f936352014-08-05 14:04:04 +10002731static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002732os_chdir_impl(PyObject *module, path_t *path)
2733/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002734{
2735 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002736
2737 Py_BEGIN_ALLOW_THREADS
2738#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002739 /* on unix, success = 0, on windows, success = !0 */
2740 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002741#else
2742#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002743 if (path->fd != -1)
2744 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002745 else
2746#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002747 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002748#endif
2749 Py_END_ALLOW_THREADS
2750
2751 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002752 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002753 }
2754
Larry Hastings2f936352014-08-05 14:04:04 +10002755 Py_RETURN_NONE;
2756}
2757
2758
2759#ifdef HAVE_FCHDIR
2760/*[clinic input]
2761os.fchdir
2762
2763 fd: fildes
2764
2765Change to the directory of the given file descriptor.
2766
2767fd must be opened on a directory, not a file.
2768Equivalent to os.chdir(fd).
2769
2770[clinic start generated code]*/
2771
Fred Drake4d1e64b2002-04-15 19:40:07 +00002772static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002773os_fchdir_impl(PyObject *module, int fd)
2774/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002775{
Larry Hastings2f936352014-08-05 14:04:04 +10002776 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002777}
2778#endif /* HAVE_FCHDIR */
2779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002780
Larry Hastings2f936352014-08-05 14:04:04 +10002781/*[clinic input]
2782os.chmod
2783
2784 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002785 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002786 On some platforms, path may also be specified as an open file descriptor.
2787 If this functionality is unavailable, using it raises an exception.
2788
2789 mode: int
2790 Operating-system mode bitfield.
2791
2792 *
2793
2794 dir_fd : dir_fd(requires='fchmodat') = None
2795 If not None, it should be a file descriptor open to a directory,
2796 and path should be relative; path will then be relative to that
2797 directory.
2798
2799 follow_symlinks: bool = True
2800 If False, and the last element of the path is a symbolic link,
2801 chmod will modify the symbolic link itself instead of the file
2802 the link points to.
2803
2804Change the access permissions of a file.
2805
2806It is an error to use dir_fd or follow_symlinks when specifying path as
2807 an open file descriptor.
2808dir_fd and follow_symlinks may not be implemented on your platform.
2809 If they are unavailable, using them will raise a NotImplementedError.
2810
2811[clinic start generated code]*/
2812
Larry Hastings2f936352014-08-05 14:04:04 +10002813static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002814os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002815 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002816/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002817{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002820#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002821 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002823
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824#ifdef HAVE_FCHMODAT
2825 int fchmodat_nofollow_unsupported = 0;
2826#endif
2827
Larry Hastings9cf065c2012-06-22 16:30:09 -07002828#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2829 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002830 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831#endif
2832
2833#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002834 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002835 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002836 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002837 result = 0;
2838 else {
2839 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002840 attr &= ~FILE_ATTRIBUTE_READONLY;
2841 else
2842 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002843 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844 }
2845 Py_END_ALLOW_THREADS
2846
2847 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002848 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002849 }
2850#else /* MS_WINDOWS */
2851 Py_BEGIN_ALLOW_THREADS
2852#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002853 if (path->fd != -1)
2854 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 else
2856#endif
2857#ifdef HAVE_LCHMOD
2858 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002859 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002860 else
2861#endif
2862#ifdef HAVE_FCHMODAT
2863 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2864 /*
2865 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2866 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002867 * and then says it isn't implemented yet.
2868 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002869 *
2870 * Once it is supported, os.chmod will automatically
2871 * support dir_fd and follow_symlinks=False. (Hopefully.)
2872 * Until then, we need to be careful what exception we raise.
2873 */
Larry Hastings2f936352014-08-05 14:04:04 +10002874 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002875 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2876 /*
2877 * But wait! We can't throw the exception without allowing threads,
2878 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2879 */
2880 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002881 result &&
2882 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2883 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002884 }
2885 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002886#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002887 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002888 Py_END_ALLOW_THREADS
2889
2890 if (result) {
2891#ifdef HAVE_FCHMODAT
2892 if (fchmodat_nofollow_unsupported) {
2893 if (dir_fd != DEFAULT_DIR_FD)
2894 dir_fd_and_follow_symlinks_invalid("chmod",
2895 dir_fd, follow_symlinks);
2896 else
2897 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002898 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002899 }
2900 else
2901#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002902 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002903 }
2904#endif
2905
Larry Hastings2f936352014-08-05 14:04:04 +10002906 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002907}
2908
Larry Hastings9cf065c2012-06-22 16:30:09 -07002909
Christian Heimes4e30a842007-11-30 22:12:06 +00002910#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002911/*[clinic input]
2912os.fchmod
2913
2914 fd: int
2915 mode: int
2916
2917Change the access permissions of the file given by file descriptor fd.
2918
2919Equivalent to os.chmod(fd, mode).
2920[clinic start generated code]*/
2921
Larry Hastings2f936352014-08-05 14:04:04 +10002922static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002923os_fchmod_impl(PyObject *module, int fd, int mode)
2924/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002925{
2926 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002927 int async_err = 0;
2928
2929 do {
2930 Py_BEGIN_ALLOW_THREADS
2931 res = fchmod(fd, mode);
2932 Py_END_ALLOW_THREADS
2933 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2934 if (res != 0)
2935 return (!async_err) ? posix_error() : NULL;
2936
Victor Stinner8c62be82010-05-06 00:08:46 +00002937 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002938}
2939#endif /* HAVE_FCHMOD */
2940
Larry Hastings2f936352014-08-05 14:04:04 +10002941
Christian Heimes4e30a842007-11-30 22:12:06 +00002942#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002943/*[clinic input]
2944os.lchmod
2945
2946 path: path_t
2947 mode: int
2948
2949Change the access permissions of a file, without following symbolic links.
2950
2951If path is a symlink, this affects the link itself rather than the target.
2952Equivalent to chmod(path, mode, follow_symlinks=False)."
2953[clinic start generated code]*/
2954
Larry Hastings2f936352014-08-05 14:04:04 +10002955static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002956os_lchmod_impl(PyObject *module, path_t *path, int mode)
2957/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002958{
Victor Stinner8c62be82010-05-06 00:08:46 +00002959 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002960 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002961 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002962 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002963 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002964 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002965 return NULL;
2966 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002967 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002968}
2969#endif /* HAVE_LCHMOD */
2970
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002971
Thomas Wouterscf297e42007-02-23 15:07:44 +00002972#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002973/*[clinic input]
2974os.chflags
2975
2976 path: path_t
2977 flags: unsigned_long(bitwise=True)
2978 follow_symlinks: bool=True
2979
2980Set file flags.
2981
2982If follow_symlinks is False, and the last element of the path is a symbolic
2983 link, chflags will change flags on the symbolic link itself instead of the
2984 file the link points to.
2985follow_symlinks may not be implemented on your platform. If it is
2986unavailable, using it will raise a NotImplementedError.
2987
2988[clinic start generated code]*/
2989
Larry Hastings2f936352014-08-05 14:04:04 +10002990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002991os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002992 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002993/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002994{
2995 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002996
2997#ifndef HAVE_LCHFLAGS
2998 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002999 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003000#endif
3001
Victor Stinner8c62be82010-05-06 00:08:46 +00003002 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003#ifdef HAVE_LCHFLAGS
3004 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003005 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003006 else
3007#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003008 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003009 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010
Larry Hastings2f936352014-08-05 14:04:04 +10003011 if (result)
3012 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003013
Larry Hastings2f936352014-08-05 14:04:04 +10003014 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003015}
3016#endif /* HAVE_CHFLAGS */
3017
Larry Hastings2f936352014-08-05 14:04:04 +10003018
Thomas Wouterscf297e42007-02-23 15:07:44 +00003019#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003020/*[clinic input]
3021os.lchflags
3022
3023 path: path_t
3024 flags: unsigned_long(bitwise=True)
3025
3026Set file flags.
3027
3028This function will not follow symbolic links.
3029Equivalent to chflags(path, flags, follow_symlinks=False).
3030[clinic start generated code]*/
3031
Larry Hastings2f936352014-08-05 14:04:04 +10003032static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003033os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3034/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003035{
Victor Stinner8c62be82010-05-06 00:08:46 +00003036 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003037 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003038 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003039 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003040 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003041 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003042 }
Victor Stinner292c8352012-10-30 02:17:38 +01003043 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003044}
3045#endif /* HAVE_LCHFLAGS */
3046
Larry Hastings2f936352014-08-05 14:04:04 +10003047
Martin v. Löwis244edc82001-10-04 22:44:26 +00003048#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003049/*[clinic input]
3050os.chroot
3051 path: path_t
3052
3053Change root directory to path.
3054
3055[clinic start generated code]*/
3056
Larry Hastings2f936352014-08-05 14:04:04 +10003057static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003058os_chroot_impl(PyObject *module, path_t *path)
3059/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003060{
3061 int res;
3062 Py_BEGIN_ALLOW_THREADS
3063 res = chroot(path->narrow);
3064 Py_END_ALLOW_THREADS
3065 if (res < 0)
3066 return path_error(path);
3067 Py_RETURN_NONE;
3068}
3069#endif /* HAVE_CHROOT */
3070
Martin v. Löwis244edc82001-10-04 22:44:26 +00003071
Guido van Rossum21142a01999-01-08 21:05:37 +00003072#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003073/*[clinic input]
3074os.fsync
3075
3076 fd: fildes
3077
3078Force write of fd to disk.
3079[clinic start generated code]*/
3080
Larry Hastings2f936352014-08-05 14:04:04 +10003081static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003082os_fsync_impl(PyObject *module, int fd)
3083/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003084{
3085 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003086}
3087#endif /* HAVE_FSYNC */
3088
Larry Hastings2f936352014-08-05 14:04:04 +10003089
Ross Lagerwall7807c352011-03-17 20:20:30 +02003090#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003091/*[clinic input]
3092os.sync
3093
3094Force write of everything to disk.
3095[clinic start generated code]*/
3096
Larry Hastings2f936352014-08-05 14:04:04 +10003097static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003098os_sync_impl(PyObject *module)
3099/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003100{
3101 Py_BEGIN_ALLOW_THREADS
3102 sync();
3103 Py_END_ALLOW_THREADS
3104 Py_RETURN_NONE;
3105}
Larry Hastings2f936352014-08-05 14:04:04 +10003106#endif /* HAVE_SYNC */
3107
Ross Lagerwall7807c352011-03-17 20:20:30 +02003108
Guido van Rossum21142a01999-01-08 21:05:37 +00003109#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003110#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003111extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3112#endif
3113
Larry Hastings2f936352014-08-05 14:04:04 +10003114/*[clinic input]
3115os.fdatasync
3116
3117 fd: fildes
3118
3119Force write of fd to disk without forcing update of metadata.
3120[clinic start generated code]*/
3121
Larry Hastings2f936352014-08-05 14:04:04 +10003122static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003123os_fdatasync_impl(PyObject *module, int fd)
3124/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003125{
3126 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003127}
3128#endif /* HAVE_FDATASYNC */
3129
3130
Fredrik Lundh10723342000-07-10 16:38:09 +00003131#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003132/*[clinic input]
3133os.chown
3134
3135 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003136 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003137
3138 uid: uid_t
3139
3140 gid: gid_t
3141
3142 *
3143
3144 dir_fd : dir_fd(requires='fchownat') = None
3145 If not None, it should be a file descriptor open to a directory,
3146 and path should be relative; path will then be relative to that
3147 directory.
3148
3149 follow_symlinks: bool = True
3150 If False, and the last element of the path is a symbolic link,
3151 stat will examine the symbolic link itself instead of the file
3152 the link points to.
3153
3154Change the owner and group id of path to the numeric uid and gid.\
3155
3156path may always be specified as a string.
3157On some platforms, path may also be specified as an open file descriptor.
3158 If this functionality is unavailable, using it raises an exception.
3159If dir_fd is not None, it should be a file descriptor open to a directory,
3160 and path should be relative; path will then be relative to that directory.
3161If follow_symlinks is False, and the last element of the path is a symbolic
3162 link, chown will modify the symbolic link itself instead of the file the
3163 link points to.
3164It is an error to use dir_fd or follow_symlinks when specifying path as
3165 an open file descriptor.
3166dir_fd and follow_symlinks may not be implemented on your platform.
3167 If they are unavailable, using them will raise a NotImplementedError.
3168
3169[clinic start generated code]*/
3170
Larry Hastings2f936352014-08-05 14:04:04 +10003171static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003172os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003173 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003174/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003175{
3176 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003177
3178#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3179 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003180 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003181#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003182 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3183 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3184 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003185
3186#ifdef __APPLE__
3187 /*
3188 * This is for Mac OS X 10.3, which doesn't have lchown.
3189 * (But we still have an lchown symbol because of weak-linking.)
3190 * It doesn't have fchownat either. So there's no possibility
3191 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003192 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003193 if ((!follow_symlinks) && (lchown == NULL)) {
3194 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003195 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003196 }
3197#endif
3198
Victor Stinner8c62be82010-05-06 00:08:46 +00003199 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003200#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003201 if (path->fd != -1)
3202 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003203 else
3204#endif
3205#ifdef HAVE_LCHOWN
3206 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003207 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003208 else
3209#endif
3210#ifdef HAVE_FCHOWNAT
3211 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003212 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003213 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3214 else
3215#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003216 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003217 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003218
Larry Hastings2f936352014-08-05 14:04:04 +10003219 if (result)
3220 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003221
Larry Hastings2f936352014-08-05 14:04:04 +10003222 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003223}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003224#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003225
Larry Hastings2f936352014-08-05 14:04:04 +10003226
Christian Heimes4e30a842007-11-30 22:12:06 +00003227#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003228/*[clinic input]
3229os.fchown
3230
3231 fd: int
3232 uid: uid_t
3233 gid: gid_t
3234
3235Change the owner and group id of the file specified by file descriptor.
3236
3237Equivalent to os.chown(fd, uid, gid).
3238
3239[clinic start generated code]*/
3240
Larry Hastings2f936352014-08-05 14:04:04 +10003241static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003242os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3243/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003244{
Victor Stinner8c62be82010-05-06 00:08:46 +00003245 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003246 int async_err = 0;
3247
3248 do {
3249 Py_BEGIN_ALLOW_THREADS
3250 res = fchown(fd, uid, gid);
3251 Py_END_ALLOW_THREADS
3252 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3253 if (res != 0)
3254 return (!async_err) ? posix_error() : NULL;
3255
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003257}
3258#endif /* HAVE_FCHOWN */
3259
Larry Hastings2f936352014-08-05 14:04:04 +10003260
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003261#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003262/*[clinic input]
3263os.lchown
3264
3265 path : path_t
3266 uid: uid_t
3267 gid: gid_t
3268
3269Change the owner and group id of path to the numeric uid and gid.
3270
3271This function will not follow symbolic links.
3272Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3273[clinic start generated code]*/
3274
Larry Hastings2f936352014-08-05 14:04:04 +10003275static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003276os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3277/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003278{
Victor Stinner8c62be82010-05-06 00:08:46 +00003279 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003280 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003281 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003283 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003284 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003285 }
Larry Hastings2f936352014-08-05 14:04:04 +10003286 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003287}
3288#endif /* HAVE_LCHOWN */
3289
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003290
Barry Warsaw53699e91996-12-10 23:23:01 +00003291static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003292posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003293{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003294 char *buf, *tmpbuf;
3295 char *cwd;
3296 const size_t chunk = 1024;
3297 size_t buflen = 0;
3298 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003299
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003300#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003301 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003302 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003303 wchar_t *wbuf2 = wbuf;
3304 PyObject *resobj;
3305 DWORD len;
3306 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003307 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 /* If the buffer is large enough, len does not include the
3309 terminating \0. If the buffer is too small, len includes
3310 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003311 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003312 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003313 if (wbuf2)
3314 len = GetCurrentDirectoryW(len, wbuf2);
3315 }
3316 Py_END_ALLOW_THREADS
3317 if (!wbuf2) {
3318 PyErr_NoMemory();
3319 return NULL;
3320 }
3321 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003322 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003323 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003324 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003325 }
3326 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003327 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003328 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003329 return resobj;
3330 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003331
3332 if (win32_warn_bytes_api())
3333 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003334#endif
3335
Victor Stinner4403d7d2015-04-25 00:16:10 +02003336 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003337 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003338 do {
3339 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003340#ifdef MS_WINDOWS
3341 if (buflen > INT_MAX) {
3342 PyErr_NoMemory();
3343 break;
3344 }
3345#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003346 tmpbuf = PyMem_RawRealloc(buf, buflen);
3347 if (tmpbuf == NULL)
3348 break;
3349
3350 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003351#ifdef MS_WINDOWS
3352 cwd = getcwd(buf, (int)buflen);
3353#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003354 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003355#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003356 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003357 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003358
3359 if (cwd == NULL) {
3360 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003361 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003362 }
3363
Victor Stinner8c62be82010-05-06 00:08:46 +00003364 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003365 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3366 else
3367 obj = PyUnicode_DecodeFSDefault(buf);
3368 PyMem_RawFree(buf);
3369
3370 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003371}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003372
Larry Hastings2f936352014-08-05 14:04:04 +10003373
3374/*[clinic input]
3375os.getcwd
3376
3377Return a unicode string representing the current working directory.
3378[clinic start generated code]*/
3379
Larry Hastings2f936352014-08-05 14:04:04 +10003380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003381os_getcwd_impl(PyObject *module)
3382/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003383{
3384 return posix_getcwd(0);
3385}
3386
Larry Hastings2f936352014-08-05 14:04:04 +10003387
3388/*[clinic input]
3389os.getcwdb
3390
3391Return a bytes string representing the current working directory.
3392[clinic start generated code]*/
3393
Larry Hastings2f936352014-08-05 14:04:04 +10003394static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003395os_getcwdb_impl(PyObject *module)
3396/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003397{
3398 return posix_getcwd(1);
3399}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003400
Larry Hastings2f936352014-08-05 14:04:04 +10003401
Larry Hastings9cf065c2012-06-22 16:30:09 -07003402#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3403#define HAVE_LINK 1
3404#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003405
Guido van Rossumb6775db1994-08-01 11:34:53 +00003406#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003407/*[clinic input]
3408
3409os.link
3410
3411 src : path_t
3412 dst : path_t
3413 *
3414 src_dir_fd : dir_fd = None
3415 dst_dir_fd : dir_fd = None
3416 follow_symlinks: bool = True
3417
3418Create a hard link to a file.
3419
3420If either src_dir_fd or dst_dir_fd is not None, it should be a file
3421 descriptor open to a directory, and the respective path string (src or dst)
3422 should be relative; the path will then be relative to that directory.
3423If follow_symlinks is False, and the last element of src is a symbolic
3424 link, link will create a link to the symbolic link itself instead of the
3425 file the link points to.
3426src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3427 platform. If they are unavailable, using them will raise a
3428 NotImplementedError.
3429[clinic start generated code]*/
3430
Larry Hastings2f936352014-08-05 14:04:04 +10003431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003432os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003433 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003434/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003435{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003436#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003437 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438#else
3439 int result;
3440#endif
3441
Larry Hastings9cf065c2012-06-22 16:30:09 -07003442#ifndef HAVE_LINKAT
3443 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3444 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003445 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 }
3447#endif
3448
Steve Dowercc16be82016-09-08 10:35:16 -07003449#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003450 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003451 PyErr_SetString(PyExc_NotImplementedError,
3452 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003453 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454 }
Steve Dowercc16be82016-09-08 10:35:16 -07003455#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003456
Brian Curtin1b9df392010-11-24 20:24:31 +00003457#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003459 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003460 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003461
Larry Hastings2f936352014-08-05 14:04:04 +10003462 if (!result)
3463 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003464#else
3465 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003466#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003467 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3468 (dst_dir_fd != DEFAULT_DIR_FD) ||
3469 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003470 result = linkat(src_dir_fd, src->narrow,
3471 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003472 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3473 else
Steve Dowercc16be82016-09-08 10:35:16 -07003474#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003475 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003477
Larry Hastings2f936352014-08-05 14:04:04 +10003478 if (result)
3479 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003480#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481
Larry Hastings2f936352014-08-05 14:04:04 +10003482 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003483}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484#endif
3485
Brian Curtin1b9df392010-11-24 20:24:31 +00003486
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003487#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003488static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003489_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003490{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491 PyObject *v;
3492 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3493 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003494 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003496 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498
Steve Dowercc16be82016-09-08 10:35:16 -07003499 WIN32_FIND_DATAW wFileData;
3500 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003501
Steve Dowercc16be82016-09-08 10:35:16 -07003502 if (!path->wide) { /* Default arg: "." */
3503 po_wchars = L".";
3504 len = 1;
3505 } else {
3506 po_wchars = path->wide;
3507 len = wcslen(path->wide);
3508 }
3509 /* The +5 is so we can append "\\*.*\0" */
3510 wnamebuf = PyMem_New(wchar_t, len + 5);
3511 if (!wnamebuf) {
3512 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003513 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 }
Steve Dowercc16be82016-09-08 10:35:16 -07003515 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003517 wchar_t wch = wnamebuf[len-1];
3518 if (wch != SEP && wch != ALTSEP && wch != L':')
3519 wnamebuf[len++] = SEP;
3520 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 }
Steve Dowercc16be82016-09-08 10:35:16 -07003522 if ((list = PyList_New(0)) == NULL) {
3523 goto exit;
3524 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003525 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003526 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003527 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 if (hFindFile == INVALID_HANDLE_VALUE) {
3529 int error = GetLastError();
3530 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531 goto exit;
3532 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003533 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003534 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 }
3536 do {
3537 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003538 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3539 wcscmp(wFileData.cFileName, L"..") != 0) {
3540 v = PyUnicode_FromWideChar(wFileData.cFileName,
3541 wcslen(wFileData.cFileName));
3542 if (path->narrow && v) {
3543 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3544 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003545 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546 Py_DECREF(list);
3547 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 break;
3549 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003551 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003552 Py_DECREF(list);
3553 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003554 break;
3555 }
3556 Py_DECREF(v);
3557 }
3558 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003559 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 Py_END_ALLOW_THREADS
3561 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3562 it got to the end of the directory. */
3563 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003565 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 }
3568 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003569
Larry Hastings9cf065c2012-06-22 16:30:09 -07003570exit:
3571 if (hFindFile != INVALID_HANDLE_VALUE) {
3572 if (FindClose(hFindFile) == FALSE) {
3573 if (list != NULL) {
3574 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003575 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003576 }
3577 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003579 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003580
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003582} /* end of _listdir_windows_no_opendir */
3583
3584#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3585
3586static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003587_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003588{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003589 PyObject *v;
3590 DIR *dirp = NULL;
3591 struct dirent *ep;
3592 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003593#ifdef HAVE_FDOPENDIR
3594 int fd = -1;
3595#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003596
Victor Stinner8c62be82010-05-06 00:08:46 +00003597 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003599 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003601 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003602 if (fd == -1)
3603 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604
Larry Hastingsfdaea062012-06-25 04:42:23 -07003605 return_str = 1;
3606
Larry Hastings9cf065c2012-06-22 16:30:09 -07003607 Py_BEGIN_ALLOW_THREADS
3608 dirp = fdopendir(fd);
3609 Py_END_ALLOW_THREADS
3610 }
3611 else
3612#endif
3613 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003614 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003615 if (path->narrow) {
3616 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003617 /* only return bytes if they specified a bytes-like object */
3618 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003619 }
3620 else {
3621 name = ".";
3622 return_str = 1;
3623 }
3624
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 Py_BEGIN_ALLOW_THREADS
3626 dirp = opendir(name);
3627 Py_END_ALLOW_THREADS
3628 }
3629
3630 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003631 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003632#ifdef HAVE_FDOPENDIR
3633 if (fd != -1) {
3634 Py_BEGIN_ALLOW_THREADS
3635 close(fd);
3636 Py_END_ALLOW_THREADS
3637 }
3638#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003639 goto exit;
3640 }
3641 if ((list = PyList_New(0)) == NULL) {
3642 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 }
3644 for (;;) {
3645 errno = 0;
3646 Py_BEGIN_ALLOW_THREADS
3647 ep = readdir(dirp);
3648 Py_END_ALLOW_THREADS
3649 if (ep == NULL) {
3650 if (errno == 0) {
3651 break;
3652 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003653 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003654 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003655 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003656 }
3657 }
3658 if (ep->d_name[0] == '.' &&
3659 (NAMLEN(ep) == 1 ||
3660 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3661 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003662 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003663 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3664 else
3665 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003666 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 break;
3669 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003670 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003672 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003673 break;
3674 }
3675 Py_DECREF(v);
3676 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003677
Larry Hastings9cf065c2012-06-22 16:30:09 -07003678exit:
3679 if (dirp != NULL) {
3680 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003681#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003682 if (fd > -1)
3683 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003684#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003685 closedir(dirp);
3686 Py_END_ALLOW_THREADS
3687 }
3688
Larry Hastings9cf065c2012-06-22 16:30:09 -07003689 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003690} /* end of _posix_listdir */
3691#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003692
Larry Hastings2f936352014-08-05 14:04:04 +10003693
3694/*[clinic input]
3695os.listdir
3696
3697 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3698
3699Return a list containing the names of the files in the directory.
3700
BNMetricsb9427072018-11-02 15:20:19 +00003701path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003702 the filenames returned will also be bytes; in all other circumstances
3703 the filenames returned will be str.
3704If path is None, uses the path='.'.
3705On some platforms, path may also be specified as an open file descriptor;\
3706 the file descriptor must refer to a directory.
3707 If this functionality is unavailable, using it raises NotImplementedError.
3708
3709The list is in arbitrary order. It does not include the special
3710entries '.' and '..' even if they are present in the directory.
3711
3712
3713[clinic start generated code]*/
3714
Larry Hastings2f936352014-08-05 14:04:04 +10003715static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003716os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003717/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003718{
3719#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3720 return _listdir_windows_no_opendir(path, NULL);
3721#else
3722 return _posix_listdir(path, NULL);
3723#endif
3724}
3725
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003726#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003727/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003728/*[clinic input]
3729os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003730
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003731 path: path_t
3732 /
3733
3734[clinic start generated code]*/
3735
3736static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003737os__getfullpathname_impl(PyObject *module, path_t *path)
3738/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003739{
Steve Dowercc16be82016-09-08 10:35:16 -07003740 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3741 wchar_t *wtemp;
3742 DWORD result;
3743 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003744
Steve Dowercc16be82016-09-08 10:35:16 -07003745 result = GetFullPathNameW(path->wide,
3746 Py_ARRAY_LENGTH(woutbuf),
3747 woutbuf, &wtemp);
3748 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3749 woutbufp = PyMem_New(wchar_t, result);
3750 if (!woutbufp)
3751 return PyErr_NoMemory();
3752 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003753 }
Steve Dowercc16be82016-09-08 10:35:16 -07003754 if (result) {
3755 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3756 if (path->narrow)
3757 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3758 } else
3759 v = win32_error_object("GetFullPathNameW", path->object);
3760 if (woutbufp != woutbuf)
3761 PyMem_Free(woutbufp);
3762 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003763}
Brian Curtind40e6f72010-07-08 21:39:08 +00003764
Brian Curtind25aef52011-06-13 15:16:04 -05003765
Larry Hastings2f936352014-08-05 14:04:04 +10003766/*[clinic input]
3767os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003768
Steve Dower23ad6d02018-02-22 10:39:10 -08003769 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003770 /
3771
3772A helper function for samepath on windows.
3773[clinic start generated code]*/
3774
Larry Hastings2f936352014-08-05 14:04:04 +10003775static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003776os__getfinalpathname_impl(PyObject *module, path_t *path)
3777/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003778{
3779 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003780 wchar_t buf[MAXPATHLEN], *target_path = buf;
3781 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003782 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003783 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003784
Steve Dower23ad6d02018-02-22 10:39:10 -08003785 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003786 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003787 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003788 0, /* desired access */
3789 0, /* share mode */
3790 NULL, /* security attributes */
3791 OPEN_EXISTING,
3792 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3793 FILE_FLAG_BACKUP_SEMANTICS,
3794 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003795 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003796
Steve Dower23ad6d02018-02-22 10:39:10 -08003797 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003798 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003799 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003800
3801 /* We have a good handle to the target, use it to determine the
3802 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003803 while (1) {
3804 Py_BEGIN_ALLOW_THREADS
3805 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3806 buf_size, VOLUME_NAME_DOS);
3807 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003808
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003809 if (!result_length) {
3810 result = win32_error_object("GetFinalPathNameByHandleW",
3811 path->object);
3812 goto cleanup;
3813 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003814
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003815 if (result_length < buf_size) {
3816 break;
3817 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003818
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003819 wchar_t *tmp;
3820 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3821 result_length * sizeof(*tmp));
3822 if (!tmp) {
3823 result = PyErr_NoMemory();
3824 goto cleanup;
3825 }
3826
3827 buf_size = result_length;
3828 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003829 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003830
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003831 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003832 if (path->narrow)
3833 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003834
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003835cleanup:
3836 if (target_path != buf) {
3837 PyMem_Free(target_path);
3838 }
3839 CloseHandle(hFile);
3840 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003841}
Brian Curtin62857742010-09-06 17:07:27 +00003842
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003843/*[clinic input]
3844os._isdir
3845
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003846 path as arg: object
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003847 /
3848
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003849Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003850[clinic start generated code]*/
3851
Brian Curtin9c669cc2011-06-08 18:17:18 -05003852static PyObject *
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003853os__isdir(PyObject *module, PyObject *arg)
3854/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003855{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003856 DWORD attributes;
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003857 path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0);
3858
3859 if (!path_converter(arg, &path)) {
3860 if (PyErr_ExceptionMatches(PyExc_ValueError)) {
3861 PyErr_Clear();
3862 Py_RETURN_FALSE;
3863 }
3864 return NULL;
3865 }
Brian Curtin9c669cc2011-06-08 18:17:18 -05003866
Steve Dowerb22a6772016-07-17 20:49:38 -07003867 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003868 attributes = GetFileAttributesW(path.wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003869 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003870
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003871 path_cleanup(&path);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003872 if (attributes == INVALID_FILE_ATTRIBUTES)
3873 Py_RETURN_FALSE;
3874
Brian Curtin9c669cc2011-06-08 18:17:18 -05003875 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3876 Py_RETURN_TRUE;
3877 else
3878 Py_RETURN_FALSE;
3879}
Tim Golden6b528062013-08-01 12:44:00 +01003880
Tim Golden6b528062013-08-01 12:44:00 +01003881
Larry Hastings2f936352014-08-05 14:04:04 +10003882/*[clinic input]
3883os._getvolumepathname
3884
Steve Dower23ad6d02018-02-22 10:39:10 -08003885 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003886
3887A helper function for ismount on Win32.
3888[clinic start generated code]*/
3889
Larry Hastings2f936352014-08-05 14:04:04 +10003890static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003891os__getvolumepathname_impl(PyObject *module, path_t *path)
3892/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003893{
3894 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003895 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003896 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003897 BOOL ret;
3898
Tim Golden6b528062013-08-01 12:44:00 +01003899 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003900 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003901
Victor Stinner850a18e2017-10-24 16:53:32 -07003902 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003903 PyErr_SetString(PyExc_OverflowError, "path too long");
3904 return NULL;
3905 }
3906
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003907 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003908 if (mountpath == NULL)
3909 return PyErr_NoMemory();
3910
3911 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003912 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003913 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003914 Py_END_ALLOW_THREADS
3915
3916 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003917 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003918 goto exit;
3919 }
3920 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003921 if (path->narrow)
3922 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003923
3924exit:
3925 PyMem_Free(mountpath);
3926 return result;
3927}
Tim Golden6b528062013-08-01 12:44:00 +01003928
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003929#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003930
Larry Hastings2f936352014-08-05 14:04:04 +10003931
3932/*[clinic input]
3933os.mkdir
3934
3935 path : path_t
3936
3937 mode: int = 0o777
3938
3939 *
3940
3941 dir_fd : dir_fd(requires='mkdirat') = None
3942
3943# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3944
3945Create a directory.
3946
3947If dir_fd is not None, it should be a file descriptor open to a directory,
3948 and path should be relative; path will then be relative to that directory.
3949dir_fd may not be implemented on your platform.
3950 If it is unavailable, using it will raise a NotImplementedError.
3951
3952The mode argument is ignored on Windows.
3953[clinic start generated code]*/
3954
Larry Hastings2f936352014-08-05 14:04:04 +10003955static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003956os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3957/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003958{
3959 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003960
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003961#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003962 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003963 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003964 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003965
Larry Hastings2f936352014-08-05 14:04:04 +10003966 if (!result)
3967 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003968#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003969 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003970#if HAVE_MKDIRAT
3971 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003972 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003973 else
3974#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003975#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003976 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003977#else
Larry Hastings2f936352014-08-05 14:04:04 +10003978 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003979#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003980 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003981 if (result < 0)
3982 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003983#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003984 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003985}
3986
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003987
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003988/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3989#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003990#include <sys/resource.h>
3991#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003992
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003993
3994#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003995/*[clinic input]
3996os.nice
3997
3998 increment: int
3999 /
4000
4001Add increment to the priority of process and return the new priority.
4002[clinic start generated code]*/
4003
Larry Hastings2f936352014-08-05 14:04:04 +10004004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004005os_nice_impl(PyObject *module, int increment)
4006/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004007{
4008 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004009
Victor Stinner8c62be82010-05-06 00:08:46 +00004010 /* There are two flavours of 'nice': one that returns the new
4011 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004012 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004013 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004014
Victor Stinner8c62be82010-05-06 00:08:46 +00004015 If we are of the nice family that returns the new priority, we
4016 need to clear errno before the call, and check if errno is filled
4017 before calling posix_error() on a returnvalue of -1, because the
4018 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004019
Victor Stinner8c62be82010-05-06 00:08:46 +00004020 errno = 0;
4021 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004022#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004023 if (value == 0)
4024 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004025#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004026 if (value == -1 && errno != 0)
4027 /* either nice() or getpriority() returned an error */
4028 return posix_error();
4029 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004030}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004031#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004032
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004033
4034#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004035/*[clinic input]
4036os.getpriority
4037
4038 which: int
4039 who: int
4040
4041Return program scheduling priority.
4042[clinic start generated code]*/
4043
Larry Hastings2f936352014-08-05 14:04:04 +10004044static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004045os_getpriority_impl(PyObject *module, int which, int who)
4046/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004047{
4048 int retval;
4049
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004050 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004051 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004052 if (errno != 0)
4053 return posix_error();
4054 return PyLong_FromLong((long)retval);
4055}
4056#endif /* HAVE_GETPRIORITY */
4057
4058
4059#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004060/*[clinic input]
4061os.setpriority
4062
4063 which: int
4064 who: int
4065 priority: int
4066
4067Set program scheduling priority.
4068[clinic start generated code]*/
4069
Larry Hastings2f936352014-08-05 14:04:04 +10004070static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004071os_setpriority_impl(PyObject *module, int which, int who, int priority)
4072/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004073{
4074 int retval;
4075
4076 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004077 if (retval == -1)
4078 return posix_error();
4079 Py_RETURN_NONE;
4080}
4081#endif /* HAVE_SETPRIORITY */
4082
4083
Barry Warsaw53699e91996-12-10 23:23:01 +00004084static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004085internal_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 +00004086{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004087 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004088 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004089
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004090#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004091 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004092 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004093#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004094 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004095#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004096
Larry Hastings9cf065c2012-06-22 16:30:09 -07004097 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4098 (dst_dir_fd != DEFAULT_DIR_FD);
4099#ifndef HAVE_RENAMEAT
4100 if (dir_fd_specified) {
4101 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004102 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004103 }
4104#endif
4105
Larry Hastings9cf065c2012-06-22 16:30:09 -07004106#ifdef MS_WINDOWS
4107 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004108 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004109 Py_END_ALLOW_THREADS
4110
Larry Hastings2f936352014-08-05 14:04:04 +10004111 if (!result)
4112 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113
4114#else
Steve Dowercc16be82016-09-08 10:35:16 -07004115 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4116 PyErr_Format(PyExc_ValueError,
4117 "%s: src and dst must be the same type", function_name);
4118 return NULL;
4119 }
4120
Larry Hastings9cf065c2012-06-22 16:30:09 -07004121 Py_BEGIN_ALLOW_THREADS
4122#ifdef HAVE_RENAMEAT
4123 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004124 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004125 else
4126#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004127 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004128 Py_END_ALLOW_THREADS
4129
Larry Hastings2f936352014-08-05 14:04:04 +10004130 if (result)
4131 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004132#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004133 Py_RETURN_NONE;
4134}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004135
Larry Hastings2f936352014-08-05 14:04:04 +10004136
4137/*[clinic input]
4138os.rename
4139
4140 src : path_t
4141 dst : path_t
4142 *
4143 src_dir_fd : dir_fd = None
4144 dst_dir_fd : dir_fd = None
4145
4146Rename a file or directory.
4147
4148If either src_dir_fd or dst_dir_fd is not None, it should be a file
4149 descriptor open to a directory, and the respective path string (src or dst)
4150 should be relative; the path will then be relative to that directory.
4151src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4152 If they are unavailable, using them will raise a NotImplementedError.
4153[clinic start generated code]*/
4154
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004155static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004156os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004157 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004158/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004159{
Larry Hastings2f936352014-08-05 14:04:04 +10004160 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004161}
4162
Larry Hastings2f936352014-08-05 14:04:04 +10004163
4164/*[clinic input]
4165os.replace = os.rename
4166
4167Rename a file or directory, overwriting the destination.
4168
4169If either src_dir_fd or dst_dir_fd is not None, it should be a file
4170 descriptor open to a directory, and the respective path string (src or dst)
4171 should be relative; the path will then be relative to that directory.
4172src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004173 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004174[clinic start generated code]*/
4175
Larry Hastings2f936352014-08-05 14:04:04 +10004176static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004177os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4178 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004179/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004180{
4181 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4182}
4183
4184
4185/*[clinic input]
4186os.rmdir
4187
4188 path: path_t
4189 *
4190 dir_fd: dir_fd(requires='unlinkat') = None
4191
4192Remove a directory.
4193
4194If dir_fd is not None, it should be a file descriptor open to a directory,
4195 and path should be relative; path will then be relative to that directory.
4196dir_fd may not be implemented on your platform.
4197 If it is unavailable, using it will raise a NotImplementedError.
4198[clinic start generated code]*/
4199
Larry Hastings2f936352014-08-05 14:04:04 +10004200static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004201os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4202/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004203{
4204 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004205
4206 Py_BEGIN_ALLOW_THREADS
4207#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004208 /* Windows, success=1, UNIX, success=0 */
4209 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004210#else
4211#ifdef HAVE_UNLINKAT
4212 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004213 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004214 else
4215#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004216 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004217#endif
4218 Py_END_ALLOW_THREADS
4219
Larry Hastings2f936352014-08-05 14:04:04 +10004220 if (result)
4221 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004222
Larry Hastings2f936352014-08-05 14:04:04 +10004223 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004224}
4225
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004226
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004227#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004228#ifdef MS_WINDOWS
4229/*[clinic input]
4230os.system -> long
4231
4232 command: Py_UNICODE
4233
4234Execute the command in a subshell.
4235[clinic start generated code]*/
4236
Larry Hastings2f936352014-08-05 14:04:04 +10004237static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004238os_system_impl(PyObject *module, const Py_UNICODE *command)
4239/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004240{
4241 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004242 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004243 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004244 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004245 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004246 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004247 return result;
4248}
4249#else /* MS_WINDOWS */
4250/*[clinic input]
4251os.system -> long
4252
4253 command: FSConverter
4254
4255Execute the command in a subshell.
4256[clinic start generated code]*/
4257
Larry Hastings2f936352014-08-05 14:04:04 +10004258static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004259os_system_impl(PyObject *module, PyObject *command)
4260/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004261{
4262 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004263 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004264 Py_BEGIN_ALLOW_THREADS
4265 result = system(bytes);
4266 Py_END_ALLOW_THREADS
4267 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004268}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004269#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004270#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004271
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004272
Larry Hastings2f936352014-08-05 14:04:04 +10004273/*[clinic input]
4274os.umask
4275
4276 mask: int
4277 /
4278
4279Set the current numeric umask and return the previous umask.
4280[clinic start generated code]*/
4281
Larry Hastings2f936352014-08-05 14:04:04 +10004282static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004283os_umask_impl(PyObject *module, int mask)
4284/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004285{
4286 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004287 if (i < 0)
4288 return posix_error();
4289 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004290}
4291
Brian Curtind40e6f72010-07-08 21:39:08 +00004292#ifdef MS_WINDOWS
4293
4294/* override the default DeleteFileW behavior so that directory
4295symlinks can be removed with this function, the same as with
4296Unix symlinks */
4297BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4298{
4299 WIN32_FILE_ATTRIBUTE_DATA info;
4300 WIN32_FIND_DATAW find_data;
4301 HANDLE find_data_handle;
4302 int is_directory = 0;
4303 int is_link = 0;
4304
4305 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4306 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004307
Brian Curtind40e6f72010-07-08 21:39:08 +00004308 /* Get WIN32_FIND_DATA structure for the path to determine if
4309 it is a symlink */
4310 if(is_directory &&
4311 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4312 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4313
4314 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004315 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4316 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4317 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4318 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004319 FindClose(find_data_handle);
4320 }
4321 }
4322 }
4323
4324 if (is_directory && is_link)
4325 return RemoveDirectoryW(lpFileName);
4326
4327 return DeleteFileW(lpFileName);
4328}
4329#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004330
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004331
Larry Hastings2f936352014-08-05 14:04:04 +10004332/*[clinic input]
4333os.unlink
4334
4335 path: path_t
4336 *
4337 dir_fd: dir_fd(requires='unlinkat')=None
4338
4339Remove a file (same as remove()).
4340
4341If dir_fd is not None, it should be a file descriptor open to a directory,
4342 and path should be relative; path will then be relative to that directory.
4343dir_fd may not be implemented on your platform.
4344 If it is unavailable, using it will raise a NotImplementedError.
4345
4346[clinic start generated code]*/
4347
Larry Hastings2f936352014-08-05 14:04:04 +10004348static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004349os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4350/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004351{
4352 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004353
4354 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004355 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004356#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004357 /* Windows, success=1, UNIX, success=0 */
4358 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004359#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004360#ifdef HAVE_UNLINKAT
4361 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004362 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004363 else
4364#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004365 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004366#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004367 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004368 Py_END_ALLOW_THREADS
4369
Larry Hastings2f936352014-08-05 14:04:04 +10004370 if (result)
4371 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004372
Larry Hastings2f936352014-08-05 14:04:04 +10004373 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004374}
4375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004376
Larry Hastings2f936352014-08-05 14:04:04 +10004377/*[clinic input]
4378os.remove = os.unlink
4379
4380Remove a file (same as unlink()).
4381
4382If dir_fd is not None, it should be a file descriptor open to a directory,
4383 and path should be relative; path will then be relative to that directory.
4384dir_fd may not be implemented on your platform.
4385 If it is unavailable, using it will raise a NotImplementedError.
4386[clinic start generated code]*/
4387
Larry Hastings2f936352014-08-05 14:04:04 +10004388static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004389os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4390/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004391{
4392 return os_unlink_impl(module, path, dir_fd);
4393}
4394
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004395
Larry Hastings605a62d2012-06-24 04:33:36 -07004396static PyStructSequence_Field uname_result_fields[] = {
4397 {"sysname", "operating system name"},
4398 {"nodename", "name of machine on network (implementation-defined)"},
4399 {"release", "operating system release"},
4400 {"version", "operating system version"},
4401 {"machine", "hardware identifier"},
4402 {NULL}
4403};
4404
4405PyDoc_STRVAR(uname_result__doc__,
4406"uname_result: Result from os.uname().\n\n\
4407This object may be accessed either as a tuple of\n\
4408 (sysname, nodename, release, version, machine),\n\
4409or via the attributes sysname, nodename, release, version, and machine.\n\
4410\n\
4411See os.uname for more information.");
4412
4413static PyStructSequence_Desc uname_result_desc = {
4414 "uname_result", /* name */
4415 uname_result__doc__, /* doc */
4416 uname_result_fields,
4417 5
4418};
4419
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004420static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004421
4422
4423#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004424/*[clinic input]
4425os.uname
4426
4427Return an object identifying the current operating system.
4428
4429The object behaves like a named tuple with the following fields:
4430 (sysname, nodename, release, version, machine)
4431
4432[clinic start generated code]*/
4433
Larry Hastings2f936352014-08-05 14:04:04 +10004434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004435os_uname_impl(PyObject *module)
4436/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004437{
Victor Stinner8c62be82010-05-06 00:08:46 +00004438 struct utsname u;
4439 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004440 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004441
Victor Stinner8c62be82010-05-06 00:08:46 +00004442 Py_BEGIN_ALLOW_THREADS
4443 res = uname(&u);
4444 Py_END_ALLOW_THREADS
4445 if (res < 0)
4446 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004447
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004448 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004449 if (value == NULL)
4450 return NULL;
4451
4452#define SET(i, field) \
4453 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004454 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004455 if (!o) { \
4456 Py_DECREF(value); \
4457 return NULL; \
4458 } \
4459 PyStructSequence_SET_ITEM(value, i, o); \
4460 } \
4461
4462 SET(0, u.sysname);
4463 SET(1, u.nodename);
4464 SET(2, u.release);
4465 SET(3, u.version);
4466 SET(4, u.machine);
4467
4468#undef SET
4469
4470 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004471}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004472#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004473
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004474
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475
4476typedef struct {
4477 int now;
4478 time_t atime_s;
4479 long atime_ns;
4480 time_t mtime_s;
4481 long mtime_ns;
4482} utime_t;
4483
4484/*
Victor Stinner484df002014-10-09 13:52:31 +02004485 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004486 * they also intentionally leak the declaration of a pointer named "time"
4487 */
4488#define UTIME_TO_TIMESPEC \
4489 struct timespec ts[2]; \
4490 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004491 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004492 time = NULL; \
4493 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004494 ts[0].tv_sec = ut->atime_s; \
4495 ts[0].tv_nsec = ut->atime_ns; \
4496 ts[1].tv_sec = ut->mtime_s; \
4497 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004498 time = ts; \
4499 } \
4500
4501#define UTIME_TO_TIMEVAL \
4502 struct timeval tv[2]; \
4503 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004504 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004505 time = NULL; \
4506 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004507 tv[0].tv_sec = ut->atime_s; \
4508 tv[0].tv_usec = ut->atime_ns / 1000; \
4509 tv[1].tv_sec = ut->mtime_s; \
4510 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004511 time = tv; \
4512 } \
4513
4514#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004515 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004516 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004517 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518 time = NULL; \
4519 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004520 u.actime = ut->atime_s; \
4521 u.modtime = ut->mtime_s; \
4522 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004523 }
4524
4525#define UTIME_TO_TIME_T \
4526 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004527 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004528 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004529 time = NULL; \
4530 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004531 timet[0] = ut->atime_s; \
4532 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004533 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004534 } \
4535
4536
Victor Stinner528a9ab2015-09-03 21:30:26 +02004537#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538
4539static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004540utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541{
4542#ifdef HAVE_UTIMENSAT
4543 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4544 UTIME_TO_TIMESPEC;
4545 return utimensat(dir_fd, path, time, flags);
4546#elif defined(HAVE_FUTIMESAT)
4547 UTIME_TO_TIMEVAL;
4548 /*
4549 * follow_symlinks will never be false here;
4550 * we only allow !follow_symlinks and dir_fd together
4551 * if we have utimensat()
4552 */
4553 assert(follow_symlinks);
4554 return futimesat(dir_fd, path, time);
4555#endif
4556}
4557
Larry Hastings2f936352014-08-05 14:04:04 +10004558 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4559#else
4560 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004561#endif
4562
Victor Stinner528a9ab2015-09-03 21:30:26 +02004563#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004564
4565static int
Victor Stinner484df002014-10-09 13:52:31 +02004566utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004567{
4568#ifdef HAVE_FUTIMENS
4569 UTIME_TO_TIMESPEC;
4570 return futimens(fd, time);
4571#else
4572 UTIME_TO_TIMEVAL;
4573 return futimes(fd, time);
4574#endif
4575}
4576
Larry Hastings2f936352014-08-05 14:04:04 +10004577 #define PATH_UTIME_HAVE_FD 1
4578#else
4579 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004580#endif
4581
Victor Stinner5ebae872015-09-22 01:29:33 +02004582#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4583# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4584#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585
Victor Stinner4552ced2015-09-21 22:37:15 +02004586#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004587
4588static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004589utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590{
4591#ifdef HAVE_UTIMENSAT
4592 UTIME_TO_TIMESPEC;
4593 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4594#else
4595 UTIME_TO_TIMEVAL;
4596 return lutimes(path, time);
4597#endif
4598}
4599
4600#endif
4601
4602#ifndef MS_WINDOWS
4603
4604static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004605utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004606{
4607#ifdef HAVE_UTIMENSAT
4608 UTIME_TO_TIMESPEC;
4609 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4610#elif defined(HAVE_UTIMES)
4611 UTIME_TO_TIMEVAL;
4612 return utimes(path, time);
4613#elif defined(HAVE_UTIME_H)
4614 UTIME_TO_UTIMBUF;
4615 return utime(path, time);
4616#else
4617 UTIME_TO_TIME_T;
4618 return utime(path, time);
4619#endif
4620}
4621
4622#endif
4623
Larry Hastings76ad59b2012-05-03 00:30:07 -07004624static int
4625split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4626{
4627 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004628 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004629 divmod = PyNumber_Divmod(py_long, billion);
4630 if (!divmod)
4631 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004632 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4633 PyErr_Format(PyExc_TypeError,
4634 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4635 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4636 goto exit;
4637 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004638 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4639 if ((*s == -1) && PyErr_Occurred())
4640 goto exit;
4641 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004642 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004643 goto exit;
4644
4645 result = 1;
4646exit:
4647 Py_XDECREF(divmod);
4648 return result;
4649}
4650
Larry Hastings2f936352014-08-05 14:04:04 +10004651
4652/*[clinic input]
4653os.utime
4654
4655 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4656 times: object = NULL
4657 *
4658 ns: object = NULL
4659 dir_fd: dir_fd(requires='futimensat') = None
4660 follow_symlinks: bool=True
4661
Martin Panter0ff89092015-09-09 01:56:53 +00004662# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004663
4664Set the access and modified time of path.
4665
4666path may always be specified as a string.
4667On some platforms, path may also be specified as an open file descriptor.
4668 If this functionality is unavailable, using it raises an exception.
4669
4670If times is not None, it must be a tuple (atime, mtime);
4671 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004672If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004673 atime_ns and mtime_ns should be expressed as integer nanoseconds
4674 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004675If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004676Specifying tuples for both times and ns is an error.
4677
4678If dir_fd is not None, it should be a file descriptor open to a directory,
4679 and path should be relative; path will then be relative to that directory.
4680If follow_symlinks is False, and the last element of the path is a symbolic
4681 link, utime will modify the symbolic link itself instead of the file the
4682 link points to.
4683It is an error to use dir_fd or follow_symlinks when specifying path
4684 as an open file descriptor.
4685dir_fd and follow_symlinks may not be available on your platform.
4686 If they are unavailable, using them will raise a NotImplementedError.
4687
4688[clinic start generated code]*/
4689
Larry Hastings2f936352014-08-05 14:04:04 +10004690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004691os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4692 int dir_fd, int follow_symlinks)
4693/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004694{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004695#ifdef MS_WINDOWS
4696 HANDLE hFile;
4697 FILETIME atime, mtime;
4698#else
4699 int result;
4700#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004701
Larry Hastings2f936352014-08-05 14:04:04 +10004702 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004703
Christian Heimesb3c87242013-08-01 00:08:16 +02004704 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004705
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706 if (times && (times != Py_None) && ns) {
4707 PyErr_SetString(PyExc_ValueError,
4708 "utime: you may specify either 'times'"
4709 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004710 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004711 }
4712
4713 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004714 time_t a_sec, m_sec;
4715 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004716 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004717 PyErr_SetString(PyExc_TypeError,
4718 "utime: 'times' must be either"
4719 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004720 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004721 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004723 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004724 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004725 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004726 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004727 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004728 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004729 utime.atime_s = a_sec;
4730 utime.atime_ns = a_nsec;
4731 utime.mtime_s = m_sec;
4732 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004733 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004735 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736 PyErr_SetString(PyExc_TypeError,
4737 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004738 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004739 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004740 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004741 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004743 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004745 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004746 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747 }
4748 else {
4749 /* times and ns are both None/unspecified. use "now". */
4750 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004751 }
4752
Victor Stinner4552ced2015-09-21 22:37:15 +02004753#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004754 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004755 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004757
Larry Hastings2f936352014-08-05 14:04:04 +10004758 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4759 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4760 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004761 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004762
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763#if !defined(HAVE_UTIMENSAT)
4764 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004765 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004766 "utime: cannot use dir_fd and follow_symlinks "
4767 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004768 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004769 }
4770#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004771
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004772#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004773 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004774 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4775 NULL, OPEN_EXISTING,
4776 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004777 Py_END_ALLOW_THREADS
4778 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004779 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004780 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004781 }
4782
Larry Hastings9cf065c2012-06-22 16:30:09 -07004783 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004784 GetSystemTimeAsFileTime(&mtime);
4785 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004786 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004787 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004788 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4789 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004790 }
4791 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4792 /* Avoid putting the file name into the error here,
4793 as that may confuse the user into believing that
4794 something is wrong with the file, when it also
4795 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004796 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004797 CloseHandle(hFile);
4798 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004799 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004800 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004801#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004802 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004803
Victor Stinner4552ced2015-09-21 22:37:15 +02004804#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004805 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004806 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004807 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004808#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809
Victor Stinner528a9ab2015-09-03 21:30:26 +02004810#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004812 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004813 else
4814#endif
4815
Victor Stinner528a9ab2015-09-03 21:30:26 +02004816#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004817 if (path->fd != -1)
4818 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004819 else
4820#endif
4821
Larry Hastings2f936352014-08-05 14:04:04 +10004822 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004823
4824 Py_END_ALLOW_THREADS
4825
4826 if (result < 0) {
4827 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004828 posix_error();
4829 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004830 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004831
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004832#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004833
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004834 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004835}
4836
Guido van Rossum3b066191991-06-04 19:40:25 +00004837/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004838
Larry Hastings2f936352014-08-05 14:04:04 +10004839
4840/*[clinic input]
4841os._exit
4842
4843 status: int
4844
4845Exit to the system with specified status, without normal exit processing.
4846[clinic start generated code]*/
4847
Larry Hastings2f936352014-08-05 14:04:04 +10004848static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004849os__exit_impl(PyObject *module, int status)
4850/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004851{
4852 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004853 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004854}
4855
Steve Dowercc16be82016-09-08 10:35:16 -07004856#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4857#define EXECV_CHAR wchar_t
4858#else
4859#define EXECV_CHAR char
4860#endif
4861
Martin v. Löwis114619e2002-10-07 06:44:21 +00004862#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4863static void
Steve Dowercc16be82016-09-08 10:35:16 -07004864free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004865{
Victor Stinner8c62be82010-05-06 00:08:46 +00004866 Py_ssize_t i;
4867 for (i = 0; i < count; i++)
4868 PyMem_Free(array[i]);
4869 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004870}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004871
Berker Peksag81816462016-09-15 20:19:47 +03004872static int
4873fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004874{
Victor Stinner8c62be82010-05-06 00:08:46 +00004875 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004876 PyObject *ub;
4877 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004878#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004879 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004880 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004881 *out = PyUnicode_AsWideCharString(ub, &size);
4882 if (*out)
4883 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004884#else
Berker Peksag81816462016-09-15 20:19:47 +03004885 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004886 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004887 size = PyBytes_GET_SIZE(ub);
4888 *out = PyMem_Malloc(size + 1);
4889 if (*out) {
4890 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4891 result = 1;
4892 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004893 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004894#endif
Berker Peksag81816462016-09-15 20:19:47 +03004895 Py_DECREF(ub);
4896 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004897}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004898#endif
4899
Ross Lagerwall7807c352011-03-17 20:20:30 +02004900#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004901static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004902parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4903{
Victor Stinner8c62be82010-05-06 00:08:46 +00004904 Py_ssize_t i, pos, envc;
4905 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004906 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004907 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004908
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 i = PyMapping_Size(env);
4910 if (i < 0)
4911 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004912 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004913 if (envlist == NULL) {
4914 PyErr_NoMemory();
4915 return NULL;
4916 }
4917 envc = 0;
4918 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004919 if (!keys)
4920 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004922 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004923 goto error;
4924 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4925 PyErr_Format(PyExc_TypeError,
4926 "env.keys() or env.values() is not a list");
4927 goto error;
4928 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004929
Victor Stinner8c62be82010-05-06 00:08:46 +00004930 for (pos = 0; pos < i; pos++) {
4931 key = PyList_GetItem(keys, pos);
4932 val = PyList_GetItem(vals, pos);
4933 if (!key || !val)
4934 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004935
Berker Peksag81816462016-09-15 20:19:47 +03004936#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4937 if (!PyUnicode_FSDecoder(key, &key2))
4938 goto error;
4939 if (!PyUnicode_FSDecoder(val, &val2)) {
4940 Py_DECREF(key2);
4941 goto error;
4942 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004943 /* Search from index 1 because on Windows starting '=' is allowed for
4944 defining hidden environment variables. */
4945 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4946 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4947 {
4948 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004949 Py_DECREF(key2);
4950 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004951 goto error;
4952 }
Berker Peksag81816462016-09-15 20:19:47 +03004953 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4954#else
4955 if (!PyUnicode_FSConverter(key, &key2))
4956 goto error;
4957 if (!PyUnicode_FSConverter(val, &val2)) {
4958 Py_DECREF(key2);
4959 goto error;
4960 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004961 if (PyBytes_GET_SIZE(key2) == 0 ||
4962 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4963 {
4964 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004965 Py_DECREF(key2);
4966 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004967 goto error;
4968 }
Berker Peksag81816462016-09-15 20:19:47 +03004969 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4970 PyBytes_AS_STRING(val2));
4971#endif
4972 Py_DECREF(key2);
4973 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004974 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004976
4977 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4978 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004979 goto error;
4980 }
Berker Peksag81816462016-09-15 20:19:47 +03004981
Steve Dowercc16be82016-09-08 10:35:16 -07004982 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004983 }
4984 Py_DECREF(vals);
4985 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004986
Victor Stinner8c62be82010-05-06 00:08:46 +00004987 envlist[envc] = 0;
4988 *envc_ptr = envc;
4989 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004990
4991error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004992 Py_XDECREF(keys);
4993 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004994 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004995 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004996}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004997
Steve Dowercc16be82016-09-08 10:35:16 -07004998static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004999parse_arglist(PyObject* argv, Py_ssize_t *argc)
5000{
5001 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005002 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005003 if (argvlist == NULL) {
5004 PyErr_NoMemory();
5005 return NULL;
5006 }
5007 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005008 PyObject* item = PySequence_ITEM(argv, i);
5009 if (item == NULL)
5010 goto fail;
5011 if (!fsconvert_strdup(item, &argvlist[i])) {
5012 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005013 goto fail;
5014 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005015 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005016 }
5017 argvlist[*argc] = NULL;
5018 return argvlist;
5019fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005020 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005021 free_string_array(argvlist, *argc);
5022 return NULL;
5023}
Steve Dowercc16be82016-09-08 10:35:16 -07005024
Ross Lagerwall7807c352011-03-17 20:20:30 +02005025#endif
5026
Larry Hastings2f936352014-08-05 14:04:04 +10005027
Ross Lagerwall7807c352011-03-17 20:20:30 +02005028#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005029/*[clinic input]
5030os.execv
5031
Steve Dowercc16be82016-09-08 10:35:16 -07005032 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005033 Path of executable file.
5034 argv: object
5035 Tuple or list of strings.
5036 /
5037
5038Execute an executable path with arguments, replacing current process.
5039[clinic start generated code]*/
5040
Larry Hastings2f936352014-08-05 14:04:04 +10005041static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005042os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5043/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005044{
Steve Dowercc16be82016-09-08 10:35:16 -07005045 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005046 Py_ssize_t argc;
5047
5048 /* execv has two arguments: (path, argv), where
5049 argv is a list or tuple of strings. */
5050
Ross Lagerwall7807c352011-03-17 20:20:30 +02005051 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5052 PyErr_SetString(PyExc_TypeError,
5053 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005054 return NULL;
5055 }
5056 argc = PySequence_Size(argv);
5057 if (argc < 1) {
5058 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005059 return NULL;
5060 }
5061
5062 argvlist = parse_arglist(argv, &argc);
5063 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005064 return NULL;
5065 }
Steve Dowerbce26262016-11-19 19:17:26 -08005066 if (!argvlist[0][0]) {
5067 PyErr_SetString(PyExc_ValueError,
5068 "execv() arg 2 first element cannot be empty");
5069 free_string_array(argvlist, argc);
5070 return NULL;
5071 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005072
Steve Dowerbce26262016-11-19 19:17:26 -08005073 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005074#ifdef HAVE_WEXECV
5075 _wexecv(path->wide, argvlist);
5076#else
5077 execv(path->narrow, argvlist);
5078#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005079 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005080
5081 /* If we get here it's definitely an error */
5082
5083 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005084 return posix_error();
5085}
5086
Larry Hastings2f936352014-08-05 14:04:04 +10005087
5088/*[clinic input]
5089os.execve
5090
5091 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5092 Path of executable file.
5093 argv: object
5094 Tuple or list of strings.
5095 env: object
5096 Dictionary of strings mapping to strings.
5097
5098Execute an executable path with arguments, replacing current process.
5099[clinic start generated code]*/
5100
Larry Hastings2f936352014-08-05 14:04:04 +10005101static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005102os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5103/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005104{
Steve Dowercc16be82016-09-08 10:35:16 -07005105 EXECV_CHAR **argvlist = NULL;
5106 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005107 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005108
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 /* execve has three arguments: (path, argv, env), where
5110 argv is a list or tuple of strings and env is a dictionary
5111 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005112
Ross Lagerwall7807c352011-03-17 20:20:30 +02005113 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005115 "execve: argv must be a tuple or list");
5116 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005117 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005118 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005119 if (argc < 1) {
5120 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5121 return NULL;
5122 }
5123
Victor Stinner8c62be82010-05-06 00:08:46 +00005124 if (!PyMapping_Check(env)) {
5125 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005126 "execve: environment must be a mapping object");
5127 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005128 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005129
Ross Lagerwall7807c352011-03-17 20:20:30 +02005130 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005132 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 }
Steve Dowerbce26262016-11-19 19:17:26 -08005134 if (!argvlist[0][0]) {
5135 PyErr_SetString(PyExc_ValueError,
5136 "execve: argv first element cannot be empty");
5137 goto fail;
5138 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005139
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 envlist = parse_envlist(env, &envc);
5141 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005142 goto fail;
5143
Steve Dowerbce26262016-11-19 19:17:26 -08005144 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005145#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005146 if (path->fd > -1)
5147 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005148 else
5149#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005150#ifdef HAVE_WEXECV
5151 _wexecve(path->wide, argvlist, envlist);
5152#else
Larry Hastings2f936352014-08-05 14:04:04 +10005153 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005154#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005155 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005156
5157 /* If we get here it's definitely an error */
5158
Alexey Izbyshev83460312018-10-20 03:28:22 +03005159 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005160
Steve Dowercc16be82016-09-08 10:35:16 -07005161 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005162 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005163 if (argvlist)
5164 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005165 return NULL;
5166}
Steve Dowercc16be82016-09-08 10:35:16 -07005167
Larry Hastings9cf065c2012-06-22 16:30:09 -07005168#endif /* HAVE_EXECV */
5169
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005170#ifdef HAVE_POSIX_SPAWN
5171
5172enum posix_spawn_file_actions_identifier {
5173 POSIX_SPAWN_OPEN,
5174 POSIX_SPAWN_CLOSE,
5175 POSIX_SPAWN_DUP2
5176};
5177
William Orr81574b82018-10-01 22:19:56 -07005178#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005179static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005180convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005181#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005182
5183static int
Victor Stinner325e4ba2019-02-01 15:47:24 +01005184parse_posix_spawn_flags(const char *func_name, PyObject *setpgroup,
5185 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005186 PyObject *setsigdef, PyObject *scheduler,
5187 posix_spawnattr_t *attrp)
5188{
5189 long all_flags = 0;
5190
5191 errno = posix_spawnattr_init(attrp);
5192 if (errno) {
5193 posix_error();
5194 return -1;
5195 }
5196
5197 if (setpgroup) {
5198 pid_t pgid = PyLong_AsPid(setpgroup);
5199 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5200 goto fail;
5201 }
5202 errno = posix_spawnattr_setpgroup(attrp, pgid);
5203 if (errno) {
5204 posix_error();
5205 goto fail;
5206 }
5207 all_flags |= POSIX_SPAWN_SETPGROUP;
5208 }
5209
5210 if (resetids) {
5211 all_flags |= POSIX_SPAWN_RESETIDS;
5212 }
5213
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005214 if (setsid) {
5215#ifdef POSIX_SPAWN_SETSID
5216 all_flags |= POSIX_SPAWN_SETSID;
5217#elif defined(POSIX_SPAWN_SETSID_NP)
5218 all_flags |= POSIX_SPAWN_SETSID_NP;
5219#else
5220 argument_unavailable_error(func_name, "setsid");
5221 return -1;
5222#endif
5223 }
5224
Pablo Galindo254a4662018-09-07 16:44:24 +01005225 if (setsigmask) {
5226 sigset_t set;
5227 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5228 goto fail;
5229 }
5230 errno = posix_spawnattr_setsigmask(attrp, &set);
5231 if (errno) {
5232 posix_error();
5233 goto fail;
5234 }
5235 all_flags |= POSIX_SPAWN_SETSIGMASK;
5236 }
5237
5238 if (setsigdef) {
5239 sigset_t set;
5240 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5241 goto fail;
5242 }
5243 errno = posix_spawnattr_setsigdefault(attrp, &set);
5244 if (errno) {
5245 posix_error();
5246 goto fail;
5247 }
5248 all_flags |= POSIX_SPAWN_SETSIGDEF;
5249 }
5250
5251 if (scheduler) {
5252#ifdef POSIX_SPAWN_SETSCHEDULER
5253 PyObject *py_schedpolicy;
5254 struct sched_param schedparam;
5255
5256 if (!PyArg_ParseTuple(scheduler, "OO&"
5257 ";A scheduler tuple must have two elements",
5258 &py_schedpolicy, convert_sched_param, &schedparam)) {
5259 goto fail;
5260 }
5261 if (py_schedpolicy != Py_None) {
5262 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5263
5264 if (schedpolicy == -1 && PyErr_Occurred()) {
5265 goto fail;
5266 }
5267 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5268 if (errno) {
5269 posix_error();
5270 goto fail;
5271 }
5272 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5273 }
5274 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5275 if (errno) {
5276 posix_error();
5277 goto fail;
5278 }
5279 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5280#else
5281 PyErr_SetString(PyExc_NotImplementedError,
5282 "The scheduler option is not supported in this system.");
5283 goto fail;
5284#endif
5285 }
5286
5287 errno = posix_spawnattr_setflags(attrp, all_flags);
5288 if (errno) {
5289 posix_error();
5290 goto fail;
5291 }
5292
5293 return 0;
5294
5295fail:
5296 (void)posix_spawnattr_destroy(attrp);
5297 return -1;
5298}
5299
5300static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005301parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005302 posix_spawn_file_actions_t *file_actionsp,
5303 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005304{
5305 PyObject *seq;
5306 PyObject *file_action = NULL;
5307 PyObject *tag_obj;
5308
5309 seq = PySequence_Fast(file_actions,
5310 "file_actions must be a sequence or None");
5311 if (seq == NULL) {
5312 return -1;
5313 }
5314
5315 errno = posix_spawn_file_actions_init(file_actionsp);
5316 if (errno) {
5317 posix_error();
5318 Py_DECREF(seq);
5319 return -1;
5320 }
5321
5322 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5323 file_action = PySequence_Fast_GET_ITEM(seq, i);
5324 Py_INCREF(file_action);
5325 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5326 PyErr_SetString(PyExc_TypeError,
5327 "Each file_actions element must be a non-empty tuple");
5328 goto fail;
5329 }
5330 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5331 if (tag == -1 && PyErr_Occurred()) {
5332 goto fail;
5333 }
5334
5335 /* Populate the file_actions object */
5336 switch (tag) {
5337 case POSIX_SPAWN_OPEN: {
5338 int fd, oflag;
5339 PyObject *path;
5340 unsigned long mode;
5341 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5342 ";A open file_action tuple must have 5 elements",
5343 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5344 &oflag, &mode))
5345 {
5346 goto fail;
5347 }
Pablo Galindocb970732018-06-19 09:19:50 +01005348 if (PyList_Append(temp_buffer, path)) {
5349 Py_DECREF(path);
5350 goto fail;
5351 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005352 errno = posix_spawn_file_actions_addopen(file_actionsp,
5353 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005354 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005355 if (errno) {
5356 posix_error();
5357 goto fail;
5358 }
5359 break;
5360 }
5361 case POSIX_SPAWN_CLOSE: {
5362 int fd;
5363 if (!PyArg_ParseTuple(file_action, "Oi"
5364 ";A close file_action tuple must have 2 elements",
5365 &tag_obj, &fd))
5366 {
5367 goto fail;
5368 }
5369 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5370 if (errno) {
5371 posix_error();
5372 goto fail;
5373 }
5374 break;
5375 }
5376 case POSIX_SPAWN_DUP2: {
5377 int fd1, fd2;
5378 if (!PyArg_ParseTuple(file_action, "Oii"
5379 ";A dup2 file_action tuple must have 3 elements",
5380 &tag_obj, &fd1, &fd2))
5381 {
5382 goto fail;
5383 }
5384 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5385 fd1, fd2);
5386 if (errno) {
5387 posix_error();
5388 goto fail;
5389 }
5390 break;
5391 }
5392 default: {
5393 PyErr_SetString(PyExc_TypeError,
5394 "Unknown file_actions identifier");
5395 goto fail;
5396 }
5397 }
5398 Py_DECREF(file_action);
5399 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005400
Serhiy Storchakaef347532018-05-01 16:45:04 +03005401 Py_DECREF(seq);
5402 return 0;
5403
5404fail:
5405 Py_DECREF(seq);
5406 Py_DECREF(file_action);
5407 (void)posix_spawn_file_actions_destroy(file_actionsp);
5408 return -1;
5409}
5410
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005411
5412static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005413py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5414 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005415 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005416 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005417{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005418 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005419 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005420 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005421 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005422 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005423 posix_spawnattr_t attr;
5424 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005425 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005426 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005427 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005428 pid_t pid;
5429 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005430
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005431 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005432 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005433 like posix.environ. */
5434
Serhiy Storchakaef347532018-05-01 16:45:04 +03005435 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005436 PyErr_Format(PyExc_TypeError,
5437 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005438 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005439 }
5440 argc = PySequence_Size(argv);
5441 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005442 PyErr_Format(PyExc_ValueError,
5443 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005444 return NULL;
5445 }
5446
5447 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005448 PyErr_Format(PyExc_TypeError,
5449 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005450 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005451 }
5452
5453 argvlist = parse_arglist(argv, &argc);
5454 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005455 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005456 }
5457 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005458 PyErr_Format(PyExc_ValueError,
5459 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005460 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005461 }
5462
5463 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005464 if (envlist == NULL) {
5465 goto exit;
5466 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005467
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005468 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005469 /* There is a bug in old versions of glibc that makes some of the
5470 * helper functions for manipulating file actions not copy the provided
5471 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5472 * copy the value of path for some old versions of glibc (<2.20).
5473 * The use of temp_buffer here is a workaround that keeps the
5474 * python objects that own the buffers alive until posix_spawn gets called.
5475 * Check https://bugs.python.org/issue33630 and
5476 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5477 temp_buffer = PyList_New(0);
5478 if (!temp_buffer) {
5479 goto exit;
5480 }
5481 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005482 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005483 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005484 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005485 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005486
Victor Stinner325e4ba2019-02-01 15:47:24 +01005487 if (parse_posix_spawn_flags(func_name, setpgroup, resetids, setsid,
5488 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005489 goto exit;
5490 }
5491 attrp = &attr;
5492
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005493 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005494#ifdef HAVE_POSIX_SPAWNP
5495 if (use_posix_spawnp) {
5496 err_code = posix_spawnp(&pid, path->narrow,
5497 file_actionsp, attrp, argvlist, envlist);
5498 }
5499 else
5500#endif /* HAVE_POSIX_SPAWNP */
5501 {
5502 err_code = posix_spawn(&pid, path->narrow,
5503 file_actionsp, attrp, argvlist, envlist);
5504 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005505 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005506
Serhiy Storchakaef347532018-05-01 16:45:04 +03005507 if (err_code) {
5508 errno = err_code;
5509 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005510 goto exit;
5511 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005512#ifdef _Py_MEMORY_SANITIZER
5513 __msan_unpoison(&pid, sizeof(pid));
5514#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005515 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005516
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005517exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005518 if (file_actionsp) {
5519 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005520 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005521 if (attrp) {
5522 (void)posix_spawnattr_destroy(attrp);
5523 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005524 if (envlist) {
5525 free_string_array(envlist, envc);
5526 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005527 if (argvlist) {
5528 free_string_array(argvlist, argc);
5529 }
Pablo Galindocb970732018-06-19 09:19:50 +01005530 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005531 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005532}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005533
5534
5535/*[clinic input]
5536
5537os.posix_spawn
5538 path: path_t
5539 Path of executable file.
5540 argv: object
5541 Tuple or list of strings.
5542 env: object
5543 Dictionary of strings mapping to strings.
5544 /
5545 *
5546 file_actions: object(c_default='NULL') = ()
5547 A sequence of file action tuples.
5548 setpgroup: object = NULL
5549 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5550 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005551 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5552 setsid: bool(accept={int}) = False
5553 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005554 setsigmask: object(c_default='NULL') = ()
5555 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5556 setsigdef: object(c_default='NULL') = ()
5557 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5558 scheduler: object = NULL
5559 A tuple with the scheduler policy (optional) and parameters.
5560
5561Execute the program specified by path in a new process.
5562[clinic start generated code]*/
5563
5564static PyObject *
5565os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5566 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005567 PyObject *setpgroup, int resetids, int setsid,
5568 PyObject *setsigmask, PyObject *setsigdef,
5569 PyObject *scheduler)
5570/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005571{
5572 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005573 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005574 scheduler);
5575}
5576 #endif /* HAVE_POSIX_SPAWN */
5577
5578
5579
5580#ifdef HAVE_POSIX_SPAWNP
5581/*[clinic input]
5582
5583os.posix_spawnp
5584 path: path_t
5585 Path of executable file.
5586 argv: object
5587 Tuple or list of strings.
5588 env: object
5589 Dictionary of strings mapping to strings.
5590 /
5591 *
5592 file_actions: object(c_default='NULL') = ()
5593 A sequence of file action tuples.
5594 setpgroup: object = NULL
5595 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5596 resetids: bool(accept={int}) = False
5597 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005598 setsid: bool(accept={int}) = False
5599 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005600 setsigmask: object(c_default='NULL') = ()
5601 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5602 setsigdef: object(c_default='NULL') = ()
5603 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5604 scheduler: object = NULL
5605 A tuple with the scheduler policy (optional) and parameters.
5606
5607Execute the program specified by path in a new process.
5608[clinic start generated code]*/
5609
5610static PyObject *
5611os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5612 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005613 PyObject *setpgroup, int resetids, int setsid,
5614 PyObject *setsigmask, PyObject *setsigdef,
5615 PyObject *scheduler)
5616/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005617{
5618 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005619 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005620 scheduler);
5621}
5622#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005623
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005624
Steve Dowercc16be82016-09-08 10:35:16 -07005625#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005626/*[clinic input]
5627os.spawnv
5628
5629 mode: int
5630 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005631 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005632 Path of executable file.
5633 argv: object
5634 Tuple or list of strings.
5635 /
5636
5637Execute the program specified by path in a new process.
5638[clinic start generated code]*/
5639
Larry Hastings2f936352014-08-05 14:04:04 +10005640static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005641os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5642/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005643{
Steve Dowercc16be82016-09-08 10:35:16 -07005644 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005645 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005646 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005647 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005648 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005649
Victor Stinner8c62be82010-05-06 00:08:46 +00005650 /* spawnv has three arguments: (mode, path, argv), where
5651 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005652
Victor Stinner8c62be82010-05-06 00:08:46 +00005653 if (PyList_Check(argv)) {
5654 argc = PyList_Size(argv);
5655 getitem = PyList_GetItem;
5656 }
5657 else if (PyTuple_Check(argv)) {
5658 argc = PyTuple_Size(argv);
5659 getitem = PyTuple_GetItem;
5660 }
5661 else {
5662 PyErr_SetString(PyExc_TypeError,
5663 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005664 return NULL;
5665 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005666 if (argc == 0) {
5667 PyErr_SetString(PyExc_ValueError,
5668 "spawnv() arg 2 cannot be empty");
5669 return NULL;
5670 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005671
Steve Dowercc16be82016-09-08 10:35:16 -07005672 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005673 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005674 return PyErr_NoMemory();
5675 }
5676 for (i = 0; i < argc; i++) {
5677 if (!fsconvert_strdup((*getitem)(argv, i),
5678 &argvlist[i])) {
5679 free_string_array(argvlist, i);
5680 PyErr_SetString(
5681 PyExc_TypeError,
5682 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005683 return NULL;
5684 }
Steve Dower93ff8722016-11-19 19:03:54 -08005685 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005686 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005687 PyErr_SetString(
5688 PyExc_ValueError,
5689 "spawnv() arg 2 first element cannot be empty");
5690 return NULL;
5691 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005692 }
5693 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005694
Victor Stinner8c62be82010-05-06 00:08:46 +00005695 if (mode == _OLD_P_OVERLAY)
5696 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005697
Victor Stinner8c62be82010-05-06 00:08:46 +00005698 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005699 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005700#ifdef HAVE_WSPAWNV
5701 spawnval = _wspawnv(mode, path->wide, argvlist);
5702#else
5703 spawnval = _spawnv(mode, path->narrow, argvlist);
5704#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005705 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005706 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005707
Victor Stinner8c62be82010-05-06 00:08:46 +00005708 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005709
Victor Stinner8c62be82010-05-06 00:08:46 +00005710 if (spawnval == -1)
5711 return posix_error();
5712 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005713 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005714}
5715
Larry Hastings2f936352014-08-05 14:04:04 +10005716/*[clinic input]
5717os.spawnve
5718
5719 mode: int
5720 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005721 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005722 Path of executable file.
5723 argv: object
5724 Tuple or list of strings.
5725 env: object
5726 Dictionary of strings mapping to strings.
5727 /
5728
5729Execute the program specified by path in a new process.
5730[clinic start generated code]*/
5731
Larry Hastings2f936352014-08-05 14:04:04 +10005732static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005733os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005734 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005735/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005736{
Steve Dowercc16be82016-09-08 10:35:16 -07005737 EXECV_CHAR **argvlist;
5738 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005740 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005741 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005742 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005743 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005744
Victor Stinner8c62be82010-05-06 00:08:46 +00005745 /* spawnve has four arguments: (mode, path, argv, env), where
5746 argv is a list or tuple of strings and env is a dictionary
5747 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005748
Victor Stinner8c62be82010-05-06 00:08:46 +00005749 if (PyList_Check(argv)) {
5750 argc = PyList_Size(argv);
5751 getitem = PyList_GetItem;
5752 }
5753 else if (PyTuple_Check(argv)) {
5754 argc = PyTuple_Size(argv);
5755 getitem = PyTuple_GetItem;
5756 }
5757 else {
5758 PyErr_SetString(PyExc_TypeError,
5759 "spawnve() arg 2 must be a tuple or list");
5760 goto fail_0;
5761 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005762 if (argc == 0) {
5763 PyErr_SetString(PyExc_ValueError,
5764 "spawnve() arg 2 cannot be empty");
5765 goto fail_0;
5766 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005767 if (!PyMapping_Check(env)) {
5768 PyErr_SetString(PyExc_TypeError,
5769 "spawnve() arg 3 must be a mapping object");
5770 goto fail_0;
5771 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005772
Steve Dowercc16be82016-09-08 10:35:16 -07005773 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005774 if (argvlist == NULL) {
5775 PyErr_NoMemory();
5776 goto fail_0;
5777 }
5778 for (i = 0; i < argc; i++) {
5779 if (!fsconvert_strdup((*getitem)(argv, i),
5780 &argvlist[i]))
5781 {
5782 lastarg = i;
5783 goto fail_1;
5784 }
Steve Dowerbce26262016-11-19 19:17:26 -08005785 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005786 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005787 PyErr_SetString(
5788 PyExc_ValueError,
5789 "spawnv() arg 2 first element cannot be empty");
5790 goto fail_1;
5791 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005792 }
5793 lastarg = argc;
5794 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005795
Victor Stinner8c62be82010-05-06 00:08:46 +00005796 envlist = parse_envlist(env, &envc);
5797 if (envlist == NULL)
5798 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005799
Victor Stinner8c62be82010-05-06 00:08:46 +00005800 if (mode == _OLD_P_OVERLAY)
5801 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005802
Victor Stinner8c62be82010-05-06 00:08:46 +00005803 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005804 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005805#ifdef HAVE_WSPAWNV
5806 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5807#else
5808 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5809#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005810 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005811 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005812
Victor Stinner8c62be82010-05-06 00:08:46 +00005813 if (spawnval == -1)
5814 (void) posix_error();
5815 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005816 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005817
Victor Stinner8c62be82010-05-06 00:08:46 +00005818 while (--envc >= 0)
5819 PyMem_DEL(envlist[envc]);
5820 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005821 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005822 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005823 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005824 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005825}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005826
Guido van Rossuma1065681999-01-25 23:20:23 +00005827#endif /* HAVE_SPAWNV */
5828
5829
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005830#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005831
5832/* Helper function to validate arguments.
5833 Returns 0 on success. non-zero on failure with a TypeError raised.
5834 If obj is non-NULL it must be callable. */
5835static int
5836check_null_or_callable(PyObject *obj, const char* obj_name)
5837{
5838 if (obj && !PyCallable_Check(obj)) {
5839 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5840 obj_name, Py_TYPE(obj)->tp_name);
5841 return -1;
5842 }
5843 return 0;
5844}
5845
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005846/*[clinic input]
5847os.register_at_fork
5848
Gregory P. Smith163468a2017-05-29 10:03:41 -07005849 *
5850 before: object=NULL
5851 A callable to be called in the parent before the fork() syscall.
5852 after_in_child: object=NULL
5853 A callable to be called in the child after fork().
5854 after_in_parent: object=NULL
5855 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005856
Gregory P. Smith163468a2017-05-29 10:03:41 -07005857Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005858
Gregory P. Smith163468a2017-05-29 10:03:41 -07005859'before' callbacks are called in reverse order.
5860'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005861
5862[clinic start generated code]*/
5863
5864static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005865os_register_at_fork_impl(PyObject *module, PyObject *before,
5866 PyObject *after_in_child, PyObject *after_in_parent)
5867/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005868{
5869 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005870
Gregory P. Smith163468a2017-05-29 10:03:41 -07005871 if (!before && !after_in_child && !after_in_parent) {
5872 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5873 return NULL;
5874 }
5875 if (check_null_or_callable(before, "before") ||
5876 check_null_or_callable(after_in_child, "after_in_child") ||
5877 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005878 return NULL;
5879 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005880 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005881
Gregory P. Smith163468a2017-05-29 10:03:41 -07005882 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005883 return NULL;
5884 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005885 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005886 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005887 }
5888 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5889 return NULL;
5890 }
5891 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005892}
5893#endif /* HAVE_FORK */
5894
5895
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005896#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005897/*[clinic input]
5898os.fork1
5899
5900Fork a child process with a single multiplexed (i.e., not bound) thread.
5901
5902Return 0 to child process and PID of child to parent process.
5903[clinic start generated code]*/
5904
Larry Hastings2f936352014-08-05 14:04:04 +10005905static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005906os_fork1_impl(PyObject *module)
5907/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005908{
Victor Stinner8c62be82010-05-06 00:08:46 +00005909 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005910
Eric Snow59032962018-09-14 14:17:20 -07005911 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5912 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5913 return NULL;
5914 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005915 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005916 pid = fork1();
5917 if (pid == 0) {
5918 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005919 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005920 } else {
5921 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005922 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005923 }
5924 if (pid == -1)
5925 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005926 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005927}
Larry Hastings2f936352014-08-05 14:04:04 +10005928#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005929
5930
Guido van Rossumad0ee831995-03-01 10:34:45 +00005931#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005932/*[clinic input]
5933os.fork
5934
5935Fork a child process.
5936
5937Return 0 to child process and PID of child to parent process.
5938[clinic start generated code]*/
5939
Larry Hastings2f936352014-08-05 14:04:04 +10005940static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005941os_fork_impl(PyObject *module)
5942/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005943{
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005945
Eric Snow59032962018-09-14 14:17:20 -07005946 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5947 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5948 return NULL;
5949 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005950 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 pid = fork();
5952 if (pid == 0) {
5953 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005954 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005955 } else {
5956 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005957 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005958 }
5959 if (pid == -1)
5960 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005961 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005962}
Larry Hastings2f936352014-08-05 14:04:04 +10005963#endif /* HAVE_FORK */
5964
Guido van Rossum85e3b011991-06-03 12:42:10 +00005965
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005966#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005967#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005968/*[clinic input]
5969os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005970
Larry Hastings2f936352014-08-05 14:04:04 +10005971 policy: int
5972
5973Get the maximum scheduling priority for policy.
5974[clinic start generated code]*/
5975
Larry Hastings2f936352014-08-05 14:04:04 +10005976static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005977os_sched_get_priority_max_impl(PyObject *module, int policy)
5978/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005979{
5980 int max;
5981
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005982 max = sched_get_priority_max(policy);
5983 if (max < 0)
5984 return posix_error();
5985 return PyLong_FromLong(max);
5986}
5987
Larry Hastings2f936352014-08-05 14:04:04 +10005988
5989/*[clinic input]
5990os.sched_get_priority_min
5991
5992 policy: int
5993
5994Get the minimum scheduling priority for policy.
5995[clinic start generated code]*/
5996
Larry Hastings2f936352014-08-05 14:04:04 +10005997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005998os_sched_get_priority_min_impl(PyObject *module, int policy)
5999/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006000{
6001 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006002 if (min < 0)
6003 return posix_error();
6004 return PyLong_FromLong(min);
6005}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006006#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6007
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006008
Larry Hastings2f936352014-08-05 14:04:04 +10006009#ifdef HAVE_SCHED_SETSCHEDULER
6010/*[clinic input]
6011os.sched_getscheduler
6012 pid: pid_t
6013 /
6014
6015Get the scheduling policy for the process identifiedy by pid.
6016
6017Passing 0 for pid returns the scheduling policy for the calling process.
6018[clinic start generated code]*/
6019
Larry Hastings2f936352014-08-05 14:04:04 +10006020static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006021os_sched_getscheduler_impl(PyObject *module, pid_t pid)
6022/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006023{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006024 int policy;
6025
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006026 policy = sched_getscheduler(pid);
6027 if (policy < 0)
6028 return posix_error();
6029 return PyLong_FromLong(policy);
6030}
Larry Hastings2f936352014-08-05 14:04:04 +10006031#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006032
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006033
William Orr81574b82018-10-01 22:19:56 -07006034#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006035/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006036class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006037
6038@classmethod
6039os.sched_param.__new__
6040
6041 sched_priority: object
6042 A scheduling parameter.
6043
6044Current has only one field: sched_priority");
6045[clinic start generated code]*/
6046
Larry Hastings2f936352014-08-05 14:04:04 +10006047static PyObject *
6048os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006049/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006050{
6051 PyObject *res;
6052
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006053 res = PyStructSequence_New(type);
6054 if (!res)
6055 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006056 Py_INCREF(sched_priority);
6057 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006058 return res;
6059}
6060
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006061
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006062PyDoc_VAR(os_sched_param__doc__);
6063
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006064static PyStructSequence_Field sched_param_fields[] = {
6065 {"sched_priority", "the scheduling priority"},
6066 {0}
6067};
6068
6069static PyStructSequence_Desc sched_param_desc = {
6070 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006071 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006072 sched_param_fields,
6073 1
6074};
6075
6076static int
6077convert_sched_param(PyObject *param, struct sched_param *res)
6078{
6079 long priority;
6080
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006081 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006082 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6083 return 0;
6084 }
6085 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6086 if (priority == -1 && PyErr_Occurred())
6087 return 0;
6088 if (priority > INT_MAX || priority < INT_MIN) {
6089 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6090 return 0;
6091 }
6092 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6093 return 1;
6094}
William Orr81574b82018-10-01 22:19:56 -07006095#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006096
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006097
6098#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006099/*[clinic input]
6100os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006101
Larry Hastings2f936352014-08-05 14:04:04 +10006102 pid: pid_t
6103 policy: int
6104 param: sched_param
6105 /
6106
6107Set the scheduling policy for the process identified by pid.
6108
6109If pid is 0, the calling process is changed.
6110param is an instance of sched_param.
6111[clinic start generated code]*/
6112
Larry Hastings2f936352014-08-05 14:04:04 +10006113static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006114os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006115 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006116/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006117{
Jesus Cea9c822272011-09-10 01:40:52 +02006118 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006119 ** sched_setscheduler() returns 0 in Linux, but the previous
6120 ** scheduling policy under Solaris/Illumos, and others.
6121 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006122 */
Larry Hastings2f936352014-08-05 14:04:04 +10006123 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006124 return posix_error();
6125 Py_RETURN_NONE;
6126}
Larry Hastings2f936352014-08-05 14:04:04 +10006127#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006128
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006129
6130#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006131/*[clinic input]
6132os.sched_getparam
6133 pid: pid_t
6134 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006135
Larry Hastings2f936352014-08-05 14:04:04 +10006136Returns scheduling parameters for the process identified by pid.
6137
6138If pid is 0, returns parameters for the calling process.
6139Return value is an instance of sched_param.
6140[clinic start generated code]*/
6141
Larry Hastings2f936352014-08-05 14:04:04 +10006142static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006143os_sched_getparam_impl(PyObject *module, pid_t pid)
6144/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006145{
6146 struct sched_param param;
6147 PyObject *result;
6148 PyObject *priority;
6149
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006150 if (sched_getparam(pid, &param))
6151 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006152 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006153 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006154 return NULL;
6155 priority = PyLong_FromLong(param.sched_priority);
6156 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006157 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006158 return NULL;
6159 }
Larry Hastings2f936352014-08-05 14:04:04 +10006160 PyStructSequence_SET_ITEM(result, 0, priority);
6161 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006162}
6163
Larry Hastings2f936352014-08-05 14:04:04 +10006164
6165/*[clinic input]
6166os.sched_setparam
6167 pid: pid_t
6168 param: sched_param
6169 /
6170
6171Set scheduling parameters for the process identified by pid.
6172
6173If pid is 0, sets parameters for the calling process.
6174param should be an instance of sched_param.
6175[clinic start generated code]*/
6176
Larry Hastings2f936352014-08-05 14:04:04 +10006177static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006178os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006179 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006180/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006181{
6182 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006183 return posix_error();
6184 Py_RETURN_NONE;
6185}
Larry Hastings2f936352014-08-05 14:04:04 +10006186#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006187
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006188
6189#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006190/*[clinic input]
6191os.sched_rr_get_interval -> double
6192 pid: pid_t
6193 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006194
Larry Hastings2f936352014-08-05 14:04:04 +10006195Return the round-robin quantum for the process identified by pid, in seconds.
6196
6197Value returned is a float.
6198[clinic start generated code]*/
6199
Larry Hastings2f936352014-08-05 14:04:04 +10006200static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006201os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6202/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006203{
6204 struct timespec interval;
6205 if (sched_rr_get_interval(pid, &interval)) {
6206 posix_error();
6207 return -1.0;
6208 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006209#ifdef _Py_MEMORY_SANITIZER
6210 __msan_unpoison(&interval, sizeof(interval));
6211#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006212 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6213}
6214#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006215
Larry Hastings2f936352014-08-05 14:04:04 +10006216
6217/*[clinic input]
6218os.sched_yield
6219
6220Voluntarily relinquish the CPU.
6221[clinic start generated code]*/
6222
Larry Hastings2f936352014-08-05 14:04:04 +10006223static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006224os_sched_yield_impl(PyObject *module)
6225/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006226{
6227 if (sched_yield())
6228 return posix_error();
6229 Py_RETURN_NONE;
6230}
6231
Benjamin Peterson2740af82011-08-02 17:41:34 -05006232#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006233/* The minimum number of CPUs allocated in a cpu_set_t */
6234static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006235
Larry Hastings2f936352014-08-05 14:04:04 +10006236/*[clinic input]
6237os.sched_setaffinity
6238 pid: pid_t
6239 mask : object
6240 /
6241
6242Set the CPU affinity of the process identified by pid to mask.
6243
6244mask should be an iterable of integers identifying CPUs.
6245[clinic start generated code]*/
6246
Larry Hastings2f936352014-08-05 14:04:04 +10006247static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006248os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6249/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006250{
Antoine Pitrou84869872012-08-04 16:16:35 +02006251 int ncpus;
6252 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006253 cpu_set_t *cpu_set = NULL;
6254 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006255
Larry Hastings2f936352014-08-05 14:04:04 +10006256 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006257 if (iterator == NULL)
6258 return NULL;
6259
6260 ncpus = NCPUS_START;
6261 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006262 cpu_set = CPU_ALLOC(ncpus);
6263 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006264 PyErr_NoMemory();
6265 goto error;
6266 }
Larry Hastings2f936352014-08-05 14:04:04 +10006267 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006268
6269 while ((item = PyIter_Next(iterator))) {
6270 long cpu;
6271 if (!PyLong_Check(item)) {
6272 PyErr_Format(PyExc_TypeError,
6273 "expected an iterator of ints, "
6274 "but iterator yielded %R",
6275 Py_TYPE(item));
6276 Py_DECREF(item);
6277 goto error;
6278 }
6279 cpu = PyLong_AsLong(item);
6280 Py_DECREF(item);
6281 if (cpu < 0) {
6282 if (!PyErr_Occurred())
6283 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6284 goto error;
6285 }
6286 if (cpu > INT_MAX - 1) {
6287 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6288 goto error;
6289 }
6290 if (cpu >= ncpus) {
6291 /* Grow CPU mask to fit the CPU number */
6292 int newncpus = ncpus;
6293 cpu_set_t *newmask;
6294 size_t newsetsize;
6295 while (newncpus <= cpu) {
6296 if (newncpus > INT_MAX / 2)
6297 newncpus = cpu + 1;
6298 else
6299 newncpus = newncpus * 2;
6300 }
6301 newmask = CPU_ALLOC(newncpus);
6302 if (newmask == NULL) {
6303 PyErr_NoMemory();
6304 goto error;
6305 }
6306 newsetsize = CPU_ALLOC_SIZE(newncpus);
6307 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006308 memcpy(newmask, cpu_set, setsize);
6309 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006310 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006311 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006312 ncpus = newncpus;
6313 }
Larry Hastings2f936352014-08-05 14:04:04 +10006314 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006315 }
6316 Py_CLEAR(iterator);
6317
Larry Hastings2f936352014-08-05 14:04:04 +10006318 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006319 posix_error();
6320 goto error;
6321 }
Larry Hastings2f936352014-08-05 14:04:04 +10006322 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006323 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006324
6325error:
Larry Hastings2f936352014-08-05 14:04:04 +10006326 if (cpu_set)
6327 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006328 Py_XDECREF(iterator);
6329 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006330}
6331
Larry Hastings2f936352014-08-05 14:04:04 +10006332
6333/*[clinic input]
6334os.sched_getaffinity
6335 pid: pid_t
6336 /
6337
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006338Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006339
6340The affinity is returned as a set of CPU identifiers.
6341[clinic start generated code]*/
6342
Larry Hastings2f936352014-08-05 14:04:04 +10006343static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006344os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006345/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006346{
Antoine Pitrou84869872012-08-04 16:16:35 +02006347 int cpu, ncpus, count;
6348 size_t setsize;
6349 cpu_set_t *mask = NULL;
6350 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006351
Antoine Pitrou84869872012-08-04 16:16:35 +02006352 ncpus = NCPUS_START;
6353 while (1) {
6354 setsize = CPU_ALLOC_SIZE(ncpus);
6355 mask = CPU_ALLOC(ncpus);
6356 if (mask == NULL)
6357 return PyErr_NoMemory();
6358 if (sched_getaffinity(pid, setsize, mask) == 0)
6359 break;
6360 CPU_FREE(mask);
6361 if (errno != EINVAL)
6362 return posix_error();
6363 if (ncpus > INT_MAX / 2) {
6364 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6365 "a large enough CPU set");
6366 return NULL;
6367 }
6368 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006369 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006370
6371 res = PySet_New(NULL);
6372 if (res == NULL)
6373 goto error;
6374 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6375 if (CPU_ISSET_S(cpu, setsize, mask)) {
6376 PyObject *cpu_num = PyLong_FromLong(cpu);
6377 --count;
6378 if (cpu_num == NULL)
6379 goto error;
6380 if (PySet_Add(res, cpu_num)) {
6381 Py_DECREF(cpu_num);
6382 goto error;
6383 }
6384 Py_DECREF(cpu_num);
6385 }
6386 }
6387 CPU_FREE(mask);
6388 return res;
6389
6390error:
6391 if (mask)
6392 CPU_FREE(mask);
6393 Py_XDECREF(res);
6394 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006395}
6396
Benjamin Peterson2740af82011-08-02 17:41:34 -05006397#endif /* HAVE_SCHED_SETAFFINITY */
6398
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006399#endif /* HAVE_SCHED_H */
6400
Larry Hastings2f936352014-08-05 14:04:04 +10006401
Neal Norwitzb59798b2003-03-21 01:43:31 +00006402/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006403/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6404#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006405#define DEV_PTY_FILE "/dev/ptc"
6406#define HAVE_DEV_PTMX
6407#else
6408#define DEV_PTY_FILE "/dev/ptmx"
6409#endif
6410
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006411#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006412#ifdef HAVE_PTY_H
6413#include <pty.h>
6414#else
6415#ifdef HAVE_LIBUTIL_H
6416#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006417#else
6418#ifdef HAVE_UTIL_H
6419#include <util.h>
6420#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006421#endif /* HAVE_LIBUTIL_H */
6422#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006423#ifdef HAVE_STROPTS_H
6424#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006425#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006426#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006427
Larry Hastings2f936352014-08-05 14:04:04 +10006428
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006429#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006430/*[clinic input]
6431os.openpty
6432
6433Open a pseudo-terminal.
6434
6435Return a tuple of (master_fd, slave_fd) containing open file descriptors
6436for both the master and slave ends.
6437[clinic start generated code]*/
6438
Larry Hastings2f936352014-08-05 14:04:04 +10006439static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006440os_openpty_impl(PyObject *module)
6441/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006442{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006443 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006444#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006445 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006446#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006447#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006448 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006449#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006450 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006451#endif
6452#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006453
Thomas Wouters70c21a12000-07-14 14:28:33 +00006454#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006456 goto posix_error;
6457
6458 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6459 goto error;
6460 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6461 goto error;
6462
Neal Norwitzb59798b2003-03-21 01:43:31 +00006463#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006464 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6465 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006466 goto posix_error;
6467 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6468 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006469
Victor Stinnerdaf45552013-08-28 00:53:59 +02006470 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006471 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006472 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006473
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006474#else
Victor Stinner000de532013-11-25 23:19:58 +01006475 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006476 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006477 goto posix_error;
6478
Victor Stinner8c62be82010-05-06 00:08:46 +00006479 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006480
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 /* change permission of slave */
6482 if (grantpt(master_fd) < 0) {
6483 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006484 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006485 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006486
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 /* unlock slave */
6488 if (unlockpt(master_fd) < 0) {
6489 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006490 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006492
Victor Stinner8c62be82010-05-06 00:08:46 +00006493 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006494
Victor Stinner8c62be82010-05-06 00:08:46 +00006495 slave_name = ptsname(master_fd); /* get name of slave */
6496 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006497 goto posix_error;
6498
6499 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006500 if (slave_fd == -1)
6501 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006502
6503 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6504 goto posix_error;
6505
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006506#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6508 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006509#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006510 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006511#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006512#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006513#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006514
Victor Stinner8c62be82010-05-06 00:08:46 +00006515 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006516
Victor Stinnerdaf45552013-08-28 00:53:59 +02006517posix_error:
6518 posix_error();
6519error:
6520 if (master_fd != -1)
6521 close(master_fd);
6522 if (slave_fd != -1)
6523 close(slave_fd);
6524 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006525}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006526#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006527
Larry Hastings2f936352014-08-05 14:04:04 +10006528
Fred Drake8cef4cf2000-06-28 16:40:38 +00006529#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006530/*[clinic input]
6531os.forkpty
6532
6533Fork a new process with a new pseudo-terminal as controlling tty.
6534
6535Returns a tuple of (pid, master_fd).
6536Like fork(), return pid of 0 to the child process,
6537and pid of child to the parent process.
6538To both, return fd of newly opened pseudo-terminal.
6539[clinic start generated code]*/
6540
Larry Hastings2f936352014-08-05 14:04:04 +10006541static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006542os_forkpty_impl(PyObject *module)
6543/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006544{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006545 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006546 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006547
Eric Snow59032962018-09-14 14:17:20 -07006548 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6549 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6550 return NULL;
6551 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006552 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006553 pid = forkpty(&master_fd, NULL, NULL, NULL);
6554 if (pid == 0) {
6555 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006556 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006557 } else {
6558 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006559 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 }
6561 if (pid == -1)
6562 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006564}
Larry Hastings2f936352014-08-05 14:04:04 +10006565#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006566
Ross Lagerwall7807c352011-03-17 20:20:30 +02006567
Guido van Rossumad0ee831995-03-01 10:34:45 +00006568#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006569/*[clinic input]
6570os.getegid
6571
6572Return the current process's effective group id.
6573[clinic start generated code]*/
6574
Larry Hastings2f936352014-08-05 14:04:04 +10006575static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006576os_getegid_impl(PyObject *module)
6577/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006578{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006579 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006580}
Larry Hastings2f936352014-08-05 14:04:04 +10006581#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006582
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006583
Guido van Rossumad0ee831995-03-01 10:34:45 +00006584#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006585/*[clinic input]
6586os.geteuid
6587
6588Return the current process's effective user id.
6589[clinic start generated code]*/
6590
Larry Hastings2f936352014-08-05 14:04:04 +10006591static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006592os_geteuid_impl(PyObject *module)
6593/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006594{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006595 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006596}
Larry Hastings2f936352014-08-05 14:04:04 +10006597#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006598
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006599
Guido van Rossumad0ee831995-03-01 10:34:45 +00006600#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006601/*[clinic input]
6602os.getgid
6603
6604Return the current process's group id.
6605[clinic start generated code]*/
6606
Larry Hastings2f936352014-08-05 14:04:04 +10006607static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006608os_getgid_impl(PyObject *module)
6609/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006610{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006611 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006612}
Larry Hastings2f936352014-08-05 14:04:04 +10006613#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006614
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006615
Berker Peksag39404992016-09-15 20:45:16 +03006616#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006617/*[clinic input]
6618os.getpid
6619
6620Return the current process id.
6621[clinic start generated code]*/
6622
Larry Hastings2f936352014-08-05 14:04:04 +10006623static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006624os_getpid_impl(PyObject *module)
6625/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006626{
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006628}
Berker Peksag39404992016-09-15 20:45:16 +03006629#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006630
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006631#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006632
6633/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006634PyDoc_STRVAR(posix_getgrouplist__doc__,
6635"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6636Returns a list of groups to which a user belongs.\n\n\
6637 user: username to lookup\n\
6638 group: base group id of the user");
6639
6640static PyObject *
6641posix_getgrouplist(PyObject *self, PyObject *args)
6642{
6643#ifdef NGROUPS_MAX
6644#define MAX_GROUPS NGROUPS_MAX
6645#else
6646 /* defined to be 16 on Solaris7, so this should be a small number */
6647#define MAX_GROUPS 64
6648#endif
6649
6650 const char *user;
6651 int i, ngroups;
6652 PyObject *list;
6653#ifdef __APPLE__
6654 int *groups, basegid;
6655#else
6656 gid_t *groups, basegid;
6657#endif
6658 ngroups = MAX_GROUPS;
6659
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006660#ifdef __APPLE__
6661 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006662 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006663#else
6664 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6665 _Py_Gid_Converter, &basegid))
6666 return NULL;
6667#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006668
6669#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006670 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006671#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006672 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006673#endif
6674 if (groups == NULL)
6675 return PyErr_NoMemory();
6676
6677 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6678 PyMem_Del(groups);
6679 return posix_error();
6680 }
6681
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006682#ifdef _Py_MEMORY_SANITIZER
6683 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6684 __msan_unpoison(&ngroups, sizeof(ngroups));
6685 __msan_unpoison(groups, ngroups*sizeof(*groups));
6686#endif
6687
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006688 list = PyList_New(ngroups);
6689 if (list == NULL) {
6690 PyMem_Del(groups);
6691 return NULL;
6692 }
6693
6694 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006695#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006696 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006697#else
6698 PyObject *o = _PyLong_FromGid(groups[i]);
6699#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006700 if (o == NULL) {
6701 Py_DECREF(list);
6702 PyMem_Del(groups);
6703 return NULL;
6704 }
6705 PyList_SET_ITEM(list, i, o);
6706 }
6707
6708 PyMem_Del(groups);
6709
6710 return list;
6711}
Larry Hastings2f936352014-08-05 14:04:04 +10006712#endif /* HAVE_GETGROUPLIST */
6713
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006714
Fred Drakec9680921999-12-13 16:37:25 +00006715#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006716/*[clinic input]
6717os.getgroups
6718
6719Return list of supplemental group IDs for the process.
6720[clinic start generated code]*/
6721
Larry Hastings2f936352014-08-05 14:04:04 +10006722static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006723os_getgroups_impl(PyObject *module)
6724/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006725{
6726 PyObject *result = NULL;
6727
Fred Drakec9680921999-12-13 16:37:25 +00006728#ifdef NGROUPS_MAX
6729#define MAX_GROUPS NGROUPS_MAX
6730#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006732#define MAX_GROUPS 64
6733#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006735
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006736 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006737 * This is a helper variable to store the intermediate result when
6738 * that happens.
6739 *
6740 * To keep the code readable the OSX behaviour is unconditional,
6741 * according to the POSIX spec this should be safe on all unix-y
6742 * systems.
6743 */
6744 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006745 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006746
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006747#ifdef __APPLE__
6748 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6749 * there are more groups than can fit in grouplist. Therefore, on OS X
6750 * always first call getgroups with length 0 to get the actual number
6751 * of groups.
6752 */
6753 n = getgroups(0, NULL);
6754 if (n < 0) {
6755 return posix_error();
6756 } else if (n <= MAX_GROUPS) {
6757 /* groups will fit in existing array */
6758 alt_grouplist = grouplist;
6759 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006760 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006761 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006762 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006763 }
6764 }
6765
6766 n = getgroups(n, alt_grouplist);
6767 if (n == -1) {
6768 if (alt_grouplist != grouplist) {
6769 PyMem_Free(alt_grouplist);
6770 }
6771 return posix_error();
6772 }
6773#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006774 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006775 if (n < 0) {
6776 if (errno == EINVAL) {
6777 n = getgroups(0, NULL);
6778 if (n == -1) {
6779 return posix_error();
6780 }
6781 if (n == 0) {
6782 /* Avoid malloc(0) */
6783 alt_grouplist = grouplist;
6784 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006785 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006786 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006787 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006788 }
6789 n = getgroups(n, alt_grouplist);
6790 if (n == -1) {
6791 PyMem_Free(alt_grouplist);
6792 return posix_error();
6793 }
6794 }
6795 } else {
6796 return posix_error();
6797 }
6798 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006799#endif
6800
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006801 result = PyList_New(n);
6802 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 int i;
6804 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006805 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006807 Py_DECREF(result);
6808 result = NULL;
6809 break;
Fred Drakec9680921999-12-13 16:37:25 +00006810 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006812 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006813 }
6814
6815 if (alt_grouplist != grouplist) {
6816 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006818
Fred Drakec9680921999-12-13 16:37:25 +00006819 return result;
6820}
Larry Hastings2f936352014-08-05 14:04:04 +10006821#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006822
Antoine Pitroub7572f02009-12-02 20:46:48 +00006823#ifdef HAVE_INITGROUPS
6824PyDoc_STRVAR(posix_initgroups__doc__,
6825"initgroups(username, gid) -> None\n\n\
6826Call the system initgroups() to initialize the group access list with all of\n\
6827the groups of which the specified username is a member, plus the specified\n\
6828group id.");
6829
Larry Hastings2f936352014-08-05 14:04:04 +10006830/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006831static PyObject *
6832posix_initgroups(PyObject *self, PyObject *args)
6833{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006834 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006835 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006836 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006837#ifdef __APPLE__
6838 int gid;
6839#else
6840 gid_t gid;
6841#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006842
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006843#ifdef __APPLE__
6844 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6845 PyUnicode_FSConverter, &oname,
6846 &gid))
6847#else
6848 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6849 PyUnicode_FSConverter, &oname,
6850 _Py_Gid_Converter, &gid))
6851#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006852 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006853 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006854
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006855 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006856 Py_DECREF(oname);
6857 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006858 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006859
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006860 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006861}
Larry Hastings2f936352014-08-05 14:04:04 +10006862#endif /* HAVE_INITGROUPS */
6863
Antoine Pitroub7572f02009-12-02 20:46:48 +00006864
Martin v. Löwis606edc12002-06-13 21:09:11 +00006865#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006866/*[clinic input]
6867os.getpgid
6868
6869 pid: pid_t
6870
6871Call the system call getpgid(), and return the result.
6872[clinic start generated code]*/
6873
Larry Hastings2f936352014-08-05 14:04:04 +10006874static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006875os_getpgid_impl(PyObject *module, pid_t pid)
6876/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006877{
6878 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006879 if (pgid < 0)
6880 return posix_error();
6881 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006882}
6883#endif /* HAVE_GETPGID */
6884
6885
Guido van Rossumb6775db1994-08-01 11:34:53 +00006886#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006887/*[clinic input]
6888os.getpgrp
6889
6890Return the current process group id.
6891[clinic start generated code]*/
6892
Larry Hastings2f936352014-08-05 14:04:04 +10006893static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006894os_getpgrp_impl(PyObject *module)
6895/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006896{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006897#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006899#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006900 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006901#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006902}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006903#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006904
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006905
Guido van Rossumb6775db1994-08-01 11:34:53 +00006906#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006907/*[clinic input]
6908os.setpgrp
6909
6910Make the current process the leader of its process group.
6911[clinic start generated code]*/
6912
Larry Hastings2f936352014-08-05 14:04:04 +10006913static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006914os_setpgrp_impl(PyObject *module)
6915/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006916{
Guido van Rossum64933891994-10-20 21:56:42 +00006917#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006918 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006919#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006920 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006921#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006923 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006924}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006925#endif /* HAVE_SETPGRP */
6926
Guido van Rossumad0ee831995-03-01 10:34:45 +00006927#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006928
6929#ifdef MS_WINDOWS
6930#include <tlhelp32.h>
6931
6932static PyObject*
6933win32_getppid()
6934{
6935 HANDLE snapshot;
6936 pid_t mypid;
6937 PyObject* result = NULL;
6938 BOOL have_record;
6939 PROCESSENTRY32 pe;
6940
6941 mypid = getpid(); /* This function never fails */
6942
6943 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6944 if (snapshot == INVALID_HANDLE_VALUE)
6945 return PyErr_SetFromWindowsErr(GetLastError());
6946
6947 pe.dwSize = sizeof(pe);
6948 have_record = Process32First(snapshot, &pe);
6949 while (have_record) {
6950 if (mypid == (pid_t)pe.th32ProcessID) {
6951 /* We could cache the ulong value in a static variable. */
6952 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6953 break;
6954 }
6955
6956 have_record = Process32Next(snapshot, &pe);
6957 }
6958
6959 /* If our loop exits and our pid was not found (result will be NULL)
6960 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6961 * error anyway, so let's raise it. */
6962 if (!result)
6963 result = PyErr_SetFromWindowsErr(GetLastError());
6964
6965 CloseHandle(snapshot);
6966
6967 return result;
6968}
6969#endif /*MS_WINDOWS*/
6970
Larry Hastings2f936352014-08-05 14:04:04 +10006971
6972/*[clinic input]
6973os.getppid
6974
6975Return the parent's process id.
6976
6977If the parent process has already exited, Windows machines will still
6978return its id; others systems will return the id of the 'init' process (1).
6979[clinic start generated code]*/
6980
Larry Hastings2f936352014-08-05 14:04:04 +10006981static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006982os_getppid_impl(PyObject *module)
6983/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006984{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006985#ifdef MS_WINDOWS
6986 return win32_getppid();
6987#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006988 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006989#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006990}
6991#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006993
Fred Drake12c6e2d1999-12-14 21:25:03 +00006994#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006995/*[clinic input]
6996os.getlogin
6997
6998Return the actual login name.
6999[clinic start generated code]*/
7000
Larry Hastings2f936352014-08-05 14:04:04 +10007001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007002os_getlogin_impl(PyObject *module)
7003/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007004{
Victor Stinner8c62be82010-05-06 00:08:46 +00007005 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007006#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007007 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007008 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007009
7010 if (GetUserNameW(user_name, &num_chars)) {
7011 /* num_chars is the number of unicode chars plus null terminator */
7012 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007013 }
7014 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007015 result = PyErr_SetFromWindowsErr(GetLastError());
7016#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007017 char *name;
7018 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007019
Victor Stinner8c62be82010-05-06 00:08:46 +00007020 errno = 0;
7021 name = getlogin();
7022 if (name == NULL) {
7023 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007024 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007025 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007026 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 }
7028 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007029 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007031#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007032 return result;
7033}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007034#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007035
Larry Hastings2f936352014-08-05 14:04:04 +10007036
Guido van Rossumad0ee831995-03-01 10:34:45 +00007037#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007038/*[clinic input]
7039os.getuid
7040
7041Return the current process's user id.
7042[clinic start generated code]*/
7043
Larry Hastings2f936352014-08-05 14:04:04 +10007044static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007045os_getuid_impl(PyObject *module)
7046/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007047{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007048 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007049}
Larry Hastings2f936352014-08-05 14:04:04 +10007050#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007051
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007052
Brian Curtineb24d742010-04-12 17:16:38 +00007053#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007054#define HAVE_KILL
7055#endif /* MS_WINDOWS */
7056
7057#ifdef HAVE_KILL
7058/*[clinic input]
7059os.kill
7060
7061 pid: pid_t
7062 signal: Py_ssize_t
7063 /
7064
7065Kill a process with a signal.
7066[clinic start generated code]*/
7067
Larry Hastings2f936352014-08-05 14:04:04 +10007068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007069os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7070/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007071#ifndef MS_WINDOWS
7072{
7073 if (kill(pid, (int)signal) == -1)
7074 return posix_error();
7075 Py_RETURN_NONE;
7076}
7077#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00007078{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007079 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007080 DWORD sig = (DWORD)signal;
7081 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007083
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 /* Console processes which share a common console can be sent CTRL+C or
7085 CTRL+BREAK events, provided they handle said events. */
7086 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007087 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007088 err = GetLastError();
7089 PyErr_SetFromWindowsErr(err);
7090 }
7091 else
7092 Py_RETURN_NONE;
7093 }
Brian Curtineb24d742010-04-12 17:16:38 +00007094
Victor Stinner8c62be82010-05-06 00:08:46 +00007095 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7096 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007097 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007098 if (handle == NULL) {
7099 err = GetLastError();
7100 return PyErr_SetFromWindowsErr(err);
7101 }
Brian Curtineb24d742010-04-12 17:16:38 +00007102
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 if (TerminateProcess(handle, sig) == 0) {
7104 err = GetLastError();
7105 result = PyErr_SetFromWindowsErr(err);
7106 } else {
7107 Py_INCREF(Py_None);
7108 result = Py_None;
7109 }
Brian Curtineb24d742010-04-12 17:16:38 +00007110
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 CloseHandle(handle);
7112 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007113}
Larry Hastings2f936352014-08-05 14:04:04 +10007114#endif /* !MS_WINDOWS */
7115#endif /* HAVE_KILL */
7116
7117
7118#ifdef HAVE_KILLPG
7119/*[clinic input]
7120os.killpg
7121
7122 pgid: pid_t
7123 signal: int
7124 /
7125
7126Kill a process group with a signal.
7127[clinic start generated code]*/
7128
Larry Hastings2f936352014-08-05 14:04:04 +10007129static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007130os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7131/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007132{
7133 /* XXX some man pages make the `pgid` parameter an int, others
7134 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7135 take the same type. Moreover, pid_t is always at least as wide as
7136 int (else compilation of this module fails), which is safe. */
7137 if (killpg(pgid, signal) == -1)
7138 return posix_error();
7139 Py_RETURN_NONE;
7140}
7141#endif /* HAVE_KILLPG */
7142
Brian Curtineb24d742010-04-12 17:16:38 +00007143
Guido van Rossumc0125471996-06-28 18:55:32 +00007144#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007145#ifdef HAVE_SYS_LOCK_H
7146#include <sys/lock.h>
7147#endif
7148
Larry Hastings2f936352014-08-05 14:04:04 +10007149/*[clinic input]
7150os.plock
7151 op: int
7152 /
7153
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007154Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007155[clinic start generated code]*/
7156
Larry Hastings2f936352014-08-05 14:04:04 +10007157static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007158os_plock_impl(PyObject *module, int op)
7159/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007160{
Victor Stinner8c62be82010-05-06 00:08:46 +00007161 if (plock(op) == -1)
7162 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007163 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007164}
Larry Hastings2f936352014-08-05 14:04:04 +10007165#endif /* HAVE_PLOCK */
7166
Guido van Rossumc0125471996-06-28 18:55:32 +00007167
Guido van Rossumb6775db1994-08-01 11:34:53 +00007168#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007169/*[clinic input]
7170os.setuid
7171
7172 uid: uid_t
7173 /
7174
7175Set the current process's user id.
7176[clinic start generated code]*/
7177
Larry Hastings2f936352014-08-05 14:04:04 +10007178static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007179os_setuid_impl(PyObject *module, uid_t uid)
7180/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007181{
Victor Stinner8c62be82010-05-06 00:08:46 +00007182 if (setuid(uid) < 0)
7183 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007184 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007185}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007186#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007188
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007189#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007190/*[clinic input]
7191os.seteuid
7192
7193 euid: uid_t
7194 /
7195
7196Set the current process's effective user id.
7197[clinic start generated code]*/
7198
Larry Hastings2f936352014-08-05 14:04:04 +10007199static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007200os_seteuid_impl(PyObject *module, uid_t euid)
7201/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007202{
7203 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007205 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007206}
7207#endif /* HAVE_SETEUID */
7208
Larry Hastings2f936352014-08-05 14:04:04 +10007209
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007210#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007211/*[clinic input]
7212os.setegid
7213
7214 egid: gid_t
7215 /
7216
7217Set the current process's effective group id.
7218[clinic start generated code]*/
7219
Larry Hastings2f936352014-08-05 14:04:04 +10007220static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007221os_setegid_impl(PyObject *module, gid_t egid)
7222/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007223{
7224 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007225 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007226 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007227}
7228#endif /* HAVE_SETEGID */
7229
Larry Hastings2f936352014-08-05 14:04:04 +10007230
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007231#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007232/*[clinic input]
7233os.setreuid
7234
7235 ruid: uid_t
7236 euid: uid_t
7237 /
7238
7239Set the current process's real and effective user ids.
7240[clinic start generated code]*/
7241
Larry Hastings2f936352014-08-05 14:04:04 +10007242static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007243os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7244/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007245{
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 if (setreuid(ruid, euid) < 0) {
7247 return posix_error();
7248 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007249 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007250 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007251}
7252#endif /* HAVE_SETREUID */
7253
Larry Hastings2f936352014-08-05 14:04:04 +10007254
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007255#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007256/*[clinic input]
7257os.setregid
7258
7259 rgid: gid_t
7260 egid: gid_t
7261 /
7262
7263Set the current process's real and effective group ids.
7264[clinic start generated code]*/
7265
Larry Hastings2f936352014-08-05 14:04:04 +10007266static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007267os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7268/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007269{
7270 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007271 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007272 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007273}
7274#endif /* HAVE_SETREGID */
7275
Larry Hastings2f936352014-08-05 14:04:04 +10007276
Guido van Rossumb6775db1994-08-01 11:34:53 +00007277#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007278/*[clinic input]
7279os.setgid
7280 gid: gid_t
7281 /
7282
7283Set the current process's group id.
7284[clinic start generated code]*/
7285
Larry Hastings2f936352014-08-05 14:04:04 +10007286static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007287os_setgid_impl(PyObject *module, gid_t gid)
7288/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007289{
Victor Stinner8c62be82010-05-06 00:08:46 +00007290 if (setgid(gid) < 0)
7291 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007292 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007293}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007294#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007295
Larry Hastings2f936352014-08-05 14:04:04 +10007296
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007297#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007298/*[clinic input]
7299os.setgroups
7300
7301 groups: object
7302 /
7303
7304Set the groups of the current process to list.
7305[clinic start generated code]*/
7306
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007307static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007308os_setgroups(PyObject *module, PyObject *groups)
7309/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007310{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007311 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007312 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007313
Victor Stinner8c62be82010-05-06 00:08:46 +00007314 if (!PySequence_Check(groups)) {
7315 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7316 return NULL;
7317 }
7318 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007319 if (len < 0) {
7320 return NULL;
7321 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007322 if (len > MAX_GROUPS) {
7323 PyErr_SetString(PyExc_ValueError, "too many groups");
7324 return NULL;
7325 }
7326 for(i = 0; i < len; i++) {
7327 PyObject *elem;
7328 elem = PySequence_GetItem(groups, i);
7329 if (!elem)
7330 return NULL;
7331 if (!PyLong_Check(elem)) {
7332 PyErr_SetString(PyExc_TypeError,
7333 "groups must be integers");
7334 Py_DECREF(elem);
7335 return NULL;
7336 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007337 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007338 Py_DECREF(elem);
7339 return NULL;
7340 }
7341 }
7342 Py_DECREF(elem);
7343 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007344
Victor Stinner8c62be82010-05-06 00:08:46 +00007345 if (setgroups(len, grouplist) < 0)
7346 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007347 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007348}
7349#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007350
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007351#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7352static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007353wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007354{
Victor Stinner8c62be82010-05-06 00:08:46 +00007355 PyObject *result;
7356 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007357 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007358
Victor Stinner8c62be82010-05-06 00:08:46 +00007359 if (pid == -1)
7360 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007361
Victor Stinner8c62be82010-05-06 00:08:46 +00007362 if (struct_rusage == NULL) {
7363 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7364 if (m == NULL)
7365 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007366 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007367 Py_DECREF(m);
7368 if (struct_rusage == NULL)
7369 return NULL;
7370 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007371
Victor Stinner8c62be82010-05-06 00:08:46 +00007372 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7373 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7374 if (!result)
7375 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007376
7377#ifndef doubletime
7378#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7379#endif
7380
Victor Stinner8c62be82010-05-06 00:08:46 +00007381 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007382 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007383 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007384 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007385#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007386 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7387 SET_INT(result, 2, ru->ru_maxrss);
7388 SET_INT(result, 3, ru->ru_ixrss);
7389 SET_INT(result, 4, ru->ru_idrss);
7390 SET_INT(result, 5, ru->ru_isrss);
7391 SET_INT(result, 6, ru->ru_minflt);
7392 SET_INT(result, 7, ru->ru_majflt);
7393 SET_INT(result, 8, ru->ru_nswap);
7394 SET_INT(result, 9, ru->ru_inblock);
7395 SET_INT(result, 10, ru->ru_oublock);
7396 SET_INT(result, 11, ru->ru_msgsnd);
7397 SET_INT(result, 12, ru->ru_msgrcv);
7398 SET_INT(result, 13, ru->ru_nsignals);
7399 SET_INT(result, 14, ru->ru_nvcsw);
7400 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007401#undef SET_INT
7402
Victor Stinner8c62be82010-05-06 00:08:46 +00007403 if (PyErr_Occurred()) {
7404 Py_DECREF(result);
7405 return NULL;
7406 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007407
Victor Stinner8c62be82010-05-06 00:08:46 +00007408 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007409}
7410#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7411
Larry Hastings2f936352014-08-05 14:04:04 +10007412
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007413#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007414/*[clinic input]
7415os.wait3
7416
7417 options: int
7418Wait for completion of a child process.
7419
7420Returns a tuple of information about the child process:
7421 (pid, status, rusage)
7422[clinic start generated code]*/
7423
Larry Hastings2f936352014-08-05 14:04:04 +10007424static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007425os_wait3_impl(PyObject *module, int options)
7426/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007427{
Victor Stinner8c62be82010-05-06 00:08:46 +00007428 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007429 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007430 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007431 WAIT_TYPE status;
7432 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007433
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007434 do {
7435 Py_BEGIN_ALLOW_THREADS
7436 pid = wait3(&status, options, &ru);
7437 Py_END_ALLOW_THREADS
7438 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7439 if (pid < 0)
7440 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007441
Victor Stinner4195b5c2012-02-08 23:03:19 +01007442 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007443}
7444#endif /* HAVE_WAIT3 */
7445
Larry Hastings2f936352014-08-05 14:04:04 +10007446
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007447#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007448/*[clinic input]
7449
7450os.wait4
7451
7452 pid: pid_t
7453 options: int
7454
7455Wait for completion of a specific child process.
7456
7457Returns a tuple of information about the child process:
7458 (pid, status, rusage)
7459[clinic start generated code]*/
7460
Larry Hastings2f936352014-08-05 14:04:04 +10007461static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007462os_wait4_impl(PyObject *module, pid_t pid, int options)
7463/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007464{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007465 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007466 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007467 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007468 WAIT_TYPE status;
7469 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007470
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007471 do {
7472 Py_BEGIN_ALLOW_THREADS
7473 res = wait4(pid, &status, options, &ru);
7474 Py_END_ALLOW_THREADS
7475 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7476 if (res < 0)
7477 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007478
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007479 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007480}
7481#endif /* HAVE_WAIT4 */
7482
Larry Hastings2f936352014-08-05 14:04:04 +10007483
Ross Lagerwall7807c352011-03-17 20:20:30 +02007484#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007485/*[clinic input]
7486os.waitid
7487
7488 idtype: idtype_t
7489 Must be one of be P_PID, P_PGID or P_ALL.
7490 id: id_t
7491 The id to wait on.
7492 options: int
7493 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7494 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7495 /
7496
7497Returns the result of waiting for a process or processes.
7498
7499Returns either waitid_result or None if WNOHANG is specified and there are
7500no children in a waitable state.
7501[clinic start generated code]*/
7502
Larry Hastings2f936352014-08-05 14:04:04 +10007503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007504os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7505/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007506{
7507 PyObject *result;
7508 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007509 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007510 siginfo_t si;
7511 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007512
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007513 do {
7514 Py_BEGIN_ALLOW_THREADS
7515 res = waitid(idtype, id, &si, options);
7516 Py_END_ALLOW_THREADS
7517 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7518 if (res < 0)
7519 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007520
7521 if (si.si_pid == 0)
7522 Py_RETURN_NONE;
7523
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007524 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007525 if (!result)
7526 return NULL;
7527
7528 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007529 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007530 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7531 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7532 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7533 if (PyErr_Occurred()) {
7534 Py_DECREF(result);
7535 return NULL;
7536 }
7537
7538 return result;
7539}
Larry Hastings2f936352014-08-05 14:04:04 +10007540#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007541
Larry Hastings2f936352014-08-05 14:04:04 +10007542
7543#if defined(HAVE_WAITPID)
7544/*[clinic input]
7545os.waitpid
7546 pid: pid_t
7547 options: int
7548 /
7549
7550Wait for completion of a given child process.
7551
7552Returns a tuple of information regarding the child process:
7553 (pid, status)
7554
7555The options argument is ignored on Windows.
7556[clinic start generated code]*/
7557
Larry Hastings2f936352014-08-05 14:04:04 +10007558static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007559os_waitpid_impl(PyObject *module, pid_t pid, int options)
7560/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007561{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007562 pid_t res;
7563 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007564 WAIT_TYPE status;
7565 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007566
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007567 do {
7568 Py_BEGIN_ALLOW_THREADS
7569 res = waitpid(pid, &status, options);
7570 Py_END_ALLOW_THREADS
7571 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7572 if (res < 0)
7573 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007574
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007575 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007576}
Tim Petersab034fa2002-02-01 11:27:43 +00007577#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007578/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007579/*[clinic input]
7580os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007581 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007582 options: int
7583 /
7584
7585Wait for completion of a given process.
7586
7587Returns a tuple of information regarding the process:
7588 (pid, status << 8)
7589
7590The options argument is ignored on Windows.
7591[clinic start generated code]*/
7592
Larry Hastings2f936352014-08-05 14:04:04 +10007593static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007594os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007595/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007596{
7597 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007598 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007599 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007600
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007601 do {
7602 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007603 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007604 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007605 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007606 Py_END_ALLOW_THREADS
7607 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007608 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007609 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007610
Victor Stinner8c62be82010-05-06 00:08:46 +00007611 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007612 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007613}
Larry Hastings2f936352014-08-05 14:04:04 +10007614#endif
7615
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007616
Guido van Rossumad0ee831995-03-01 10:34:45 +00007617#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007618/*[clinic input]
7619os.wait
7620
7621Wait for completion of a child process.
7622
7623Returns a tuple of information about the child process:
7624 (pid, status)
7625[clinic start generated code]*/
7626
Larry Hastings2f936352014-08-05 14:04:04 +10007627static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007628os_wait_impl(PyObject *module)
7629/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007630{
Victor Stinner8c62be82010-05-06 00:08:46 +00007631 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007632 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007633 WAIT_TYPE status;
7634 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007635
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007636 do {
7637 Py_BEGIN_ALLOW_THREADS
7638 pid = wait(&status);
7639 Py_END_ALLOW_THREADS
7640 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7641 if (pid < 0)
7642 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007643
Victor Stinner8c62be82010-05-06 00:08:46 +00007644 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007645}
Larry Hastings2f936352014-08-05 14:04:04 +10007646#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007647
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007648
Larry Hastings9cf065c2012-06-22 16:30:09 -07007649#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007650/*[clinic input]
7651os.readlink
7652
7653 path: path_t
7654 *
7655 dir_fd: dir_fd(requires='readlinkat') = None
7656
7657Return a string representing the path to which the symbolic link points.
7658
7659If dir_fd is not None, it should be a file descriptor open to a directory,
7660and path should be relative; path will then be relative to that directory.
7661
7662dir_fd may not be implemented on your platform. If it is unavailable,
7663using it will raise a NotImplementedError.
7664[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007665
Barry Warsaw53699e91996-12-10 23:23:01 +00007666static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007667os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7668/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007669{
Berker Peksage0b5b202018-08-15 13:03:41 +03007670#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007671 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007672 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007673
7674 Py_BEGIN_ALLOW_THREADS
7675#ifdef HAVE_READLINKAT
7676 if (dir_fd != DEFAULT_DIR_FD)
7677 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7678 else
7679#endif
7680 length = readlink(path->narrow, buffer, MAXPATHLEN);
7681 Py_END_ALLOW_THREADS
7682
7683 if (length < 0) {
7684 return path_error(path);
7685 }
7686 buffer[length] = '\0';
7687
7688 if (PyUnicode_Check(path->object))
7689 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7690 else
7691 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007692#elif defined(MS_WINDOWS)
7693 DWORD n_bytes_returned;
7694 DWORD io_result;
7695 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007696 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7697 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7698 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007699 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007700
Larry Hastings2f936352014-08-05 14:04:04 +10007701 /* First get a handle to the reparse point */
7702 Py_BEGIN_ALLOW_THREADS
7703 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007704 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007705 0,
7706 0,
7707 0,
7708 OPEN_EXISTING,
7709 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7710 0);
7711 Py_END_ALLOW_THREADS
7712
Berker Peksage0b5b202018-08-15 13:03:41 +03007713 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007714 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007715 }
Larry Hastings2f936352014-08-05 14:04:04 +10007716
7717 Py_BEGIN_ALLOW_THREADS
7718 /* New call DeviceIoControl to read the reparse point */
7719 io_result = DeviceIoControl(
7720 reparse_point_handle,
7721 FSCTL_GET_REPARSE_POINT,
7722 0, 0, /* in buffer */
7723 target_buffer, sizeof(target_buffer),
7724 &n_bytes_returned,
7725 0 /* we're not using OVERLAPPED_IO */
7726 );
7727 CloseHandle(reparse_point_handle);
7728 Py_END_ALLOW_THREADS
7729
Berker Peksage0b5b202018-08-15 13:03:41 +03007730 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007731 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007732 }
Larry Hastings2f936352014-08-05 14:04:04 +10007733
7734 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7735 {
7736 PyErr_SetString(PyExc_ValueError,
7737 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007738 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007739 }
SSE43c34aad2018-02-13 00:10:35 +07007740 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7741 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007742
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007743 result = PyUnicode_FromWideChar(print_name,
7744 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7745 if (path->narrow) {
7746 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007747 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007748 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007749#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007750}
Berker Peksage0b5b202018-08-15 13:03:41 +03007751#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007752
Larry Hastings9cf065c2012-06-22 16:30:09 -07007753#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007754
7755#if defined(MS_WINDOWS)
7756
Steve Dower6921e732018-03-05 14:26:08 -08007757/* Remove the last portion of the path - return 0 on success */
7758static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007759_dirnameW(WCHAR *path)
7760{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007761 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007762 size_t length = wcsnlen_s(path, MAX_PATH);
7763 if (length == MAX_PATH) {
7764 return -1;
7765 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007766
7767 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007768 for(ptr = path + length; ptr != path; ptr--) {
7769 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007770 break;
Steve Dower6921e732018-03-05 14:26:08 -08007771 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007772 }
7773 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007774 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007775}
7776
Victor Stinner31b3b922013-06-05 01:49:17 +02007777/* Is this path absolute? */
7778static int
7779_is_absW(const WCHAR *path)
7780{
Steve Dower6921e732018-03-05 14:26:08 -08007781 return path[0] == L'\\' || path[0] == L'/' ||
7782 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007783}
7784
Steve Dower6921e732018-03-05 14:26:08 -08007785/* join root and rest with a backslash - return 0 on success */
7786static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007787_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7788{
Victor Stinner31b3b922013-06-05 01:49:17 +02007789 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007790 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007791 }
7792
Steve Dower6921e732018-03-05 14:26:08 -08007793 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7794 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007795 }
Steve Dower6921e732018-03-05 14:26:08 -08007796
7797 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7798 return -1;
7799 }
7800
7801 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007802}
7803
Victor Stinner31b3b922013-06-05 01:49:17 +02007804/* Return True if the path at src relative to dest is a directory */
7805static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007806_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007807{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007808 WIN32_FILE_ATTRIBUTE_DATA src_info;
7809 WCHAR dest_parent[MAX_PATH];
7810 WCHAR src_resolved[MAX_PATH] = L"";
7811
7812 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007813 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7814 _dirnameW(dest_parent)) {
7815 return 0;
7816 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007817 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007818 if (_joinW(src_resolved, dest_parent, src)) {
7819 return 0;
7820 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007821 return (
7822 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7823 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7824 );
7825}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007826#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007827
Larry Hastings2f936352014-08-05 14:04:04 +10007828
7829/*[clinic input]
7830os.symlink
7831 src: path_t
7832 dst: path_t
7833 target_is_directory: bool = False
7834 *
7835 dir_fd: dir_fd(requires='symlinkat')=None
7836
7837# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7838
7839Create a symbolic link pointing to src named dst.
7840
7841target_is_directory is required on Windows if the target is to be
7842 interpreted as a directory. (On Windows, symlink requires
7843 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7844 target_is_directory is ignored on non-Windows platforms.
7845
7846If dir_fd is not None, it should be a file descriptor open to a directory,
7847 and path should be relative; path will then be relative to that directory.
7848dir_fd may not be implemented on your platform.
7849 If it is unavailable, using it will raise a NotImplementedError.
7850
7851[clinic start generated code]*/
7852
Larry Hastings2f936352014-08-05 14:04:04 +10007853static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007854os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007855 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007856/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007857{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007858#ifdef MS_WINDOWS
7859 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007860 DWORD flags = 0;
7861
7862 /* Assumed true, set to false if detected to not be available. */
7863 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007864#else
7865 int result;
7866#endif
7867
Larry Hastings9cf065c2012-06-22 16:30:09 -07007868#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007869
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007870 if (windows_has_symlink_unprivileged_flag) {
7871 /* Allow non-admin symlinks if system allows it. */
7872 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
7873 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007874
Larry Hastings9cf065c2012-06-22 16:30:09 -07007875 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007876 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007877 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
7878 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
7879 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
7880 }
7881
7882 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08007883 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007884 Py_END_ALLOW_THREADS
7885
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007886 if (windows_has_symlink_unprivileged_flag && !result &&
7887 ERROR_INVALID_PARAMETER == GetLastError()) {
7888
7889 Py_BEGIN_ALLOW_THREADS
7890 _Py_BEGIN_SUPPRESS_IPH
7891 /* This error might be caused by
7892 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
7893 Try again, and update windows_has_symlink_unprivileged_flag if we
7894 are successful this time.
7895
7896 NOTE: There is a risk of a race condition here if there are other
7897 conditions than the flag causing ERROR_INVALID_PARAMETER, and
7898 another process (or thread) changes that condition in between our
7899 calls to CreateSymbolicLink.
7900 */
7901 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
7902 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
7903 _Py_END_SUPPRESS_IPH
7904 Py_END_ALLOW_THREADS
7905
7906 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
7907 windows_has_symlink_unprivileged_flag = FALSE;
7908 }
7909 }
7910
Larry Hastings2f936352014-08-05 14:04:04 +10007911 if (!result)
7912 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007913
7914#else
7915
Steve Dower6921e732018-03-05 14:26:08 -08007916 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7917 PyErr_SetString(PyExc_ValueError,
7918 "symlink: src and dst must be the same type");
7919 return NULL;
7920 }
7921
Larry Hastings9cf065c2012-06-22 16:30:09 -07007922 Py_BEGIN_ALLOW_THREADS
7923#if HAVE_SYMLINKAT
7924 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007925 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007926 else
7927#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007928 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007929 Py_END_ALLOW_THREADS
7930
Larry Hastings2f936352014-08-05 14:04:04 +10007931 if (result)
7932 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007933#endif
7934
Larry Hastings2f936352014-08-05 14:04:04 +10007935 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007936}
7937#endif /* HAVE_SYMLINK */
7938
Larry Hastings9cf065c2012-06-22 16:30:09 -07007939
Brian Curtind40e6f72010-07-08 21:39:08 +00007940
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007941
Larry Hastings605a62d2012-06-24 04:33:36 -07007942static PyStructSequence_Field times_result_fields[] = {
7943 {"user", "user time"},
7944 {"system", "system time"},
7945 {"children_user", "user time of children"},
7946 {"children_system", "system time of children"},
7947 {"elapsed", "elapsed time since an arbitrary point in the past"},
7948 {NULL}
7949};
7950
7951PyDoc_STRVAR(times_result__doc__,
7952"times_result: Result from os.times().\n\n\
7953This object may be accessed either as a tuple of\n\
7954 (user, system, children_user, children_system, elapsed),\n\
7955or via the attributes user, system, children_user, children_system,\n\
7956and elapsed.\n\
7957\n\
7958See os.times for more information.");
7959
7960static PyStructSequence_Desc times_result_desc = {
7961 "times_result", /* name */
7962 times_result__doc__, /* doc */
7963 times_result_fields,
7964 5
7965};
7966
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007967static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07007968
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007969#ifdef MS_WINDOWS
7970#define HAVE_TIMES /* mandatory, for the method table */
7971#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007972
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007973#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007974
7975static PyObject *
7976build_times_result(double user, double system,
7977 double children_user, double children_system,
7978 double elapsed)
7979{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007980 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07007981 if (value == NULL)
7982 return NULL;
7983
7984#define SET(i, field) \
7985 { \
7986 PyObject *o = PyFloat_FromDouble(field); \
7987 if (!o) { \
7988 Py_DECREF(value); \
7989 return NULL; \
7990 } \
7991 PyStructSequence_SET_ITEM(value, i, o); \
7992 } \
7993
7994 SET(0, user);
7995 SET(1, system);
7996 SET(2, children_user);
7997 SET(3, children_system);
7998 SET(4, elapsed);
7999
8000#undef SET
8001
8002 return value;
8003}
8004
Larry Hastings605a62d2012-06-24 04:33:36 -07008005
Larry Hastings2f936352014-08-05 14:04:04 +10008006#ifndef MS_WINDOWS
8007#define NEED_TICKS_PER_SECOND
8008static long ticks_per_second = -1;
8009#endif /* MS_WINDOWS */
8010
8011/*[clinic input]
8012os.times
8013
8014Return a collection containing process timing information.
8015
8016The object returned behaves like a named tuple with these fields:
8017 (utime, stime, cutime, cstime, elapsed_time)
8018All fields are floating point numbers.
8019[clinic start generated code]*/
8020
Larry Hastings2f936352014-08-05 14:04:04 +10008021static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008022os_times_impl(PyObject *module)
8023/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008024#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008025{
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 FILETIME create, exit, kernel, user;
8027 HANDLE hProc;
8028 hProc = GetCurrentProcess();
8029 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8030 /* The fields of a FILETIME structure are the hi and lo part
8031 of a 64-bit value expressed in 100 nanosecond units.
8032 1e7 is one second in such units; 1e-7 the inverse.
8033 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8034 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008035 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 (double)(user.dwHighDateTime*429.4967296 +
8037 user.dwLowDateTime*1e-7),
8038 (double)(kernel.dwHighDateTime*429.4967296 +
8039 kernel.dwLowDateTime*1e-7),
8040 (double)0,
8041 (double)0,
8042 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008043}
Larry Hastings2f936352014-08-05 14:04:04 +10008044#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008045{
Larry Hastings2f936352014-08-05 14:04:04 +10008046
8047
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008048 struct tms t;
8049 clock_t c;
8050 errno = 0;
8051 c = times(&t);
8052 if (c == (clock_t) -1)
8053 return posix_error();
8054 return build_times_result(
8055 (double)t.tms_utime / ticks_per_second,
8056 (double)t.tms_stime / ticks_per_second,
8057 (double)t.tms_cutime / ticks_per_second,
8058 (double)t.tms_cstime / ticks_per_second,
8059 (double)c / ticks_per_second);
8060}
Larry Hastings2f936352014-08-05 14:04:04 +10008061#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008062#endif /* HAVE_TIMES */
8063
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008064
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008065#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008066/*[clinic input]
8067os.getsid
8068
8069 pid: pid_t
8070 /
8071
8072Call the system call getsid(pid) and return the result.
8073[clinic start generated code]*/
8074
Larry Hastings2f936352014-08-05 14:04:04 +10008075static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008076os_getsid_impl(PyObject *module, pid_t pid)
8077/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008078{
Victor Stinner8c62be82010-05-06 00:08:46 +00008079 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008080 sid = getsid(pid);
8081 if (sid < 0)
8082 return posix_error();
8083 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008084}
8085#endif /* HAVE_GETSID */
8086
8087
Guido van Rossumb6775db1994-08-01 11:34:53 +00008088#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008089/*[clinic input]
8090os.setsid
8091
8092Call the system call setsid().
8093[clinic start generated code]*/
8094
Larry Hastings2f936352014-08-05 14:04:04 +10008095static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008096os_setsid_impl(PyObject *module)
8097/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008098{
Victor Stinner8c62be82010-05-06 00:08:46 +00008099 if (setsid() < 0)
8100 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008101 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008102}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008103#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008104
Larry Hastings2f936352014-08-05 14:04:04 +10008105
Guido van Rossumb6775db1994-08-01 11:34:53 +00008106#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008107/*[clinic input]
8108os.setpgid
8109
8110 pid: pid_t
8111 pgrp: pid_t
8112 /
8113
8114Call the system call setpgid(pid, pgrp).
8115[clinic start generated code]*/
8116
Larry Hastings2f936352014-08-05 14:04:04 +10008117static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008118os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8119/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008120{
Victor Stinner8c62be82010-05-06 00:08:46 +00008121 if (setpgid(pid, pgrp) < 0)
8122 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008123 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008124}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008125#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008127
Guido van Rossumb6775db1994-08-01 11:34:53 +00008128#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008129/*[clinic input]
8130os.tcgetpgrp
8131
8132 fd: int
8133 /
8134
8135Return the process group associated with the terminal specified by fd.
8136[clinic start generated code]*/
8137
Larry Hastings2f936352014-08-05 14:04:04 +10008138static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008139os_tcgetpgrp_impl(PyObject *module, int fd)
8140/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008141{
8142 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008143 if (pgid < 0)
8144 return posix_error();
8145 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008146}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008147#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008148
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008149
Guido van Rossumb6775db1994-08-01 11:34:53 +00008150#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008151/*[clinic input]
8152os.tcsetpgrp
8153
8154 fd: int
8155 pgid: pid_t
8156 /
8157
8158Set the process group associated with the terminal specified by fd.
8159[clinic start generated code]*/
8160
Larry Hastings2f936352014-08-05 14:04:04 +10008161static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008162os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8163/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008164{
Victor Stinner8c62be82010-05-06 00:08:46 +00008165 if (tcsetpgrp(fd, pgid) < 0)
8166 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008167 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008168}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008169#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008170
Guido van Rossum687dd131993-05-17 08:34:16 +00008171/* Functions acting on file descriptors */
8172
Victor Stinnerdaf45552013-08-28 00:53:59 +02008173#ifdef O_CLOEXEC
8174extern int _Py_open_cloexec_works;
8175#endif
8176
Larry Hastings2f936352014-08-05 14:04:04 +10008177
8178/*[clinic input]
8179os.open -> int
8180 path: path_t
8181 flags: int
8182 mode: int = 0o777
8183 *
8184 dir_fd: dir_fd(requires='openat') = None
8185
8186# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8187
8188Open a file for low level IO. Returns a file descriptor (integer).
8189
8190If dir_fd is not None, it should be a file descriptor open to a directory,
8191 and path should be relative; path will then be relative to that directory.
8192dir_fd may not be implemented on your platform.
8193 If it is unavailable, using it will raise a NotImplementedError.
8194[clinic start generated code]*/
8195
Larry Hastings2f936352014-08-05 14:04:04 +10008196static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008197os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8198/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008199{
8200 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008201 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008202
Victor Stinnerdaf45552013-08-28 00:53:59 +02008203#ifdef O_CLOEXEC
8204 int *atomic_flag_works = &_Py_open_cloexec_works;
8205#elif !defined(MS_WINDOWS)
8206 int *atomic_flag_works = NULL;
8207#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008208
Victor Stinnerdaf45552013-08-28 00:53:59 +02008209#ifdef MS_WINDOWS
8210 flags |= O_NOINHERIT;
8211#elif defined(O_CLOEXEC)
8212 flags |= O_CLOEXEC;
8213#endif
8214
Steve Dower8fc89802015-04-12 00:26:27 -04008215 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008216 do {
8217 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008218#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008219 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008220#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008221#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008222 if (dir_fd != DEFAULT_DIR_FD)
8223 fd = openat(dir_fd, path->narrow, flags, mode);
8224 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008225#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008226 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008227#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008228 Py_END_ALLOW_THREADS
8229 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008230 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008231
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008232 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008233 if (!async_err)
8234 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008235 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008236 }
8237
Victor Stinnerdaf45552013-08-28 00:53:59 +02008238#ifndef MS_WINDOWS
8239 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8240 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008241 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008242 }
8243#endif
8244
Larry Hastings2f936352014-08-05 14:04:04 +10008245 return fd;
8246}
8247
8248
8249/*[clinic input]
8250os.close
8251
8252 fd: int
8253
8254Close a file descriptor.
8255[clinic start generated code]*/
8256
Barry Warsaw53699e91996-12-10 23:23:01 +00008257static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008258os_close_impl(PyObject *module, int fd)
8259/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008260{
Larry Hastings2f936352014-08-05 14:04:04 +10008261 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008262 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8263 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8264 * for more details.
8265 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008266 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008267 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008268 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008269 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008270 Py_END_ALLOW_THREADS
8271 if (res < 0)
8272 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008273 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008274}
8275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008276
Larry Hastings2f936352014-08-05 14:04:04 +10008277/*[clinic input]
8278os.closerange
8279
8280 fd_low: int
8281 fd_high: int
8282 /
8283
8284Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8285[clinic start generated code]*/
8286
Larry Hastings2f936352014-08-05 14:04:04 +10008287static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008288os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8289/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008290{
8291 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008292 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008293 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008294 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008295 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008296 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008297 Py_END_ALLOW_THREADS
8298 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008299}
8300
8301
Larry Hastings2f936352014-08-05 14:04:04 +10008302/*[clinic input]
8303os.dup -> int
8304
8305 fd: int
8306 /
8307
8308Return a duplicate of a file descriptor.
8309[clinic start generated code]*/
8310
Larry Hastings2f936352014-08-05 14:04:04 +10008311static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008312os_dup_impl(PyObject *module, int fd)
8313/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008314{
8315 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008316}
8317
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008318
Larry Hastings2f936352014-08-05 14:04:04 +10008319/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008320os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008321 fd: int
8322 fd2: int
8323 inheritable: bool=True
8324
8325Duplicate file descriptor.
8326[clinic start generated code]*/
8327
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008328static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008329os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008330/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008331{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008332 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008333#if defined(HAVE_DUP3) && \
8334 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8335 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008336 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008337#endif
8338
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008339 if (fd < 0 || fd2 < 0) {
8340 posix_error();
8341 return -1;
8342 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008343
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008344 /* dup2() can fail with EINTR if the target FD is already open, because it
8345 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8346 * upon close(), and therefore below.
8347 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008348#ifdef MS_WINDOWS
8349 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008350 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008351 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008352 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008353 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008354 if (res < 0) {
8355 posix_error();
8356 return -1;
8357 }
8358 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008359
8360 /* Character files like console cannot be make non-inheritable */
8361 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8362 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008363 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008364 }
8365
8366#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8367 Py_BEGIN_ALLOW_THREADS
8368 if (!inheritable)
8369 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8370 else
8371 res = dup2(fd, fd2);
8372 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008373 if (res < 0) {
8374 posix_error();
8375 return -1;
8376 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008377
8378#else
8379
8380#ifdef HAVE_DUP3
8381 if (!inheritable && dup3_works != 0) {
8382 Py_BEGIN_ALLOW_THREADS
8383 res = dup3(fd, fd2, O_CLOEXEC);
8384 Py_END_ALLOW_THREADS
8385 if (res < 0) {
8386 if (dup3_works == -1)
8387 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008388 if (dup3_works) {
8389 posix_error();
8390 return -1;
8391 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008392 }
8393 }
8394
8395 if (inheritable || dup3_works == 0)
8396 {
8397#endif
8398 Py_BEGIN_ALLOW_THREADS
8399 res = dup2(fd, fd2);
8400 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008401 if (res < 0) {
8402 posix_error();
8403 return -1;
8404 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008405
8406 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8407 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008408 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008409 }
8410#ifdef HAVE_DUP3
8411 }
8412#endif
8413
8414#endif
8415
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008416 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008417}
8418
Larry Hastings2f936352014-08-05 14:04:04 +10008419
Ross Lagerwall7807c352011-03-17 20:20:30 +02008420#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008421/*[clinic input]
8422os.lockf
8423
8424 fd: int
8425 An open file descriptor.
8426 command: int
8427 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8428 length: Py_off_t
8429 The number of bytes to lock, starting at the current position.
8430 /
8431
8432Apply, test or remove a POSIX lock on an open file descriptor.
8433
8434[clinic start generated code]*/
8435
Larry Hastings2f936352014-08-05 14:04:04 +10008436static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008437os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8438/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008439{
8440 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008441
8442 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008443 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008444 Py_END_ALLOW_THREADS
8445
8446 if (res < 0)
8447 return posix_error();
8448
8449 Py_RETURN_NONE;
8450}
Larry Hastings2f936352014-08-05 14:04:04 +10008451#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008452
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008453
Larry Hastings2f936352014-08-05 14:04:04 +10008454/*[clinic input]
8455os.lseek -> Py_off_t
8456
8457 fd: int
8458 position: Py_off_t
8459 how: int
8460 /
8461
8462Set the position of a file descriptor. Return the new position.
8463
8464Return the new cursor position in number of bytes
8465relative to the beginning of the file.
8466[clinic start generated code]*/
8467
Larry Hastings2f936352014-08-05 14:04:04 +10008468static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008469os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8470/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008471{
8472 Py_off_t result;
8473
Guido van Rossum687dd131993-05-17 08:34:16 +00008474#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008475 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8476 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008477 case 0: how = SEEK_SET; break;
8478 case 1: how = SEEK_CUR; break;
8479 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008480 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008481#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008482
Victor Stinner8c62be82010-05-06 00:08:46 +00008483 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008484 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008485#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008486 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008487#else
Larry Hastings2f936352014-08-05 14:04:04 +10008488 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008489#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008490 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008491 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008492 if (result < 0)
8493 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008494
Larry Hastings2f936352014-08-05 14:04:04 +10008495 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008496}
8497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008498
Larry Hastings2f936352014-08-05 14:04:04 +10008499/*[clinic input]
8500os.read
8501 fd: int
8502 length: Py_ssize_t
8503 /
8504
8505Read from a file descriptor. Returns a bytes object.
8506[clinic start generated code]*/
8507
Larry Hastings2f936352014-08-05 14:04:04 +10008508static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008509os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8510/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008511{
Victor Stinner8c62be82010-05-06 00:08:46 +00008512 Py_ssize_t n;
8513 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008514
8515 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008516 errno = EINVAL;
8517 return posix_error();
8518 }
Larry Hastings2f936352014-08-05 14:04:04 +10008519
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008520 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008521
8522 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008523 if (buffer == NULL)
8524 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008525
Victor Stinner66aab0c2015-03-19 22:53:20 +01008526 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8527 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008528 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008529 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008530 }
Larry Hastings2f936352014-08-05 14:04:04 +10008531
8532 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008533 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008534
Victor Stinner8c62be82010-05-06 00:08:46 +00008535 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008536}
8537
Ross Lagerwall7807c352011-03-17 20:20:30 +02008538#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008539 || defined(__APPLE__))) \
8540 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8541 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8542static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008543iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008544{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008545 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008546
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008547 *iov = PyMem_New(struct iovec, cnt);
8548 if (*iov == NULL) {
8549 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008550 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008551 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008552
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008553 *buf = PyMem_New(Py_buffer, cnt);
8554 if (*buf == NULL) {
8555 PyMem_Del(*iov);
8556 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008557 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008558 }
8559
8560 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008561 PyObject *item = PySequence_GetItem(seq, i);
8562 if (item == NULL)
8563 goto fail;
8564 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8565 Py_DECREF(item);
8566 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008567 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008568 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008569 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008570 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008571 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008572 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008573
8574fail:
8575 PyMem_Del(*iov);
8576 for (j = 0; j < i; j++) {
8577 PyBuffer_Release(&(*buf)[j]);
8578 }
8579 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008580 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008581}
8582
8583static void
8584iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8585{
8586 int i;
8587 PyMem_Del(iov);
8588 for (i = 0; i < cnt; i++) {
8589 PyBuffer_Release(&buf[i]);
8590 }
8591 PyMem_Del(buf);
8592}
8593#endif
8594
Larry Hastings2f936352014-08-05 14:04:04 +10008595
Ross Lagerwall7807c352011-03-17 20:20:30 +02008596#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008597/*[clinic input]
8598os.readv -> Py_ssize_t
8599
8600 fd: int
8601 buffers: object
8602 /
8603
8604Read from a file descriptor fd into an iterable of buffers.
8605
8606The buffers should be mutable buffers accepting bytes.
8607readv will transfer data into each buffer until it is full
8608and then move on to the next buffer in the sequence to hold
8609the rest of the data.
8610
8611readv returns the total number of bytes read,
8612which may be less than the total capacity of all the buffers.
8613[clinic start generated code]*/
8614
Larry Hastings2f936352014-08-05 14:04:04 +10008615static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008616os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8617/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008618{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008619 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008620 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008621 struct iovec *iov;
8622 Py_buffer *buf;
8623
Larry Hastings2f936352014-08-05 14:04:04 +10008624 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008625 PyErr_SetString(PyExc_TypeError,
8626 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008627 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008628 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008629
Larry Hastings2f936352014-08-05 14:04:04 +10008630 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008631 if (cnt < 0)
8632 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008633
8634 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8635 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008636
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008637 do {
8638 Py_BEGIN_ALLOW_THREADS
8639 n = readv(fd, iov, cnt);
8640 Py_END_ALLOW_THREADS
8641 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008642
8643 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008644 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008645 if (!async_err)
8646 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008647 return -1;
8648 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008649
Larry Hastings2f936352014-08-05 14:04:04 +10008650 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008651}
Larry Hastings2f936352014-08-05 14:04:04 +10008652#endif /* HAVE_READV */
8653
Ross Lagerwall7807c352011-03-17 20:20:30 +02008654
8655#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008656/*[clinic input]
8657# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8658os.pread
8659
8660 fd: int
8661 length: int
8662 offset: Py_off_t
8663 /
8664
8665Read a number of bytes from a file descriptor starting at a particular offset.
8666
8667Read length bytes from file descriptor fd, starting at offset bytes from
8668the beginning of the file. The file offset remains unchanged.
8669[clinic start generated code]*/
8670
Larry Hastings2f936352014-08-05 14:04:04 +10008671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008672os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8673/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008674{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008675 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008676 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008677 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008678
Larry Hastings2f936352014-08-05 14:04:04 +10008679 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008680 errno = EINVAL;
8681 return posix_error();
8682 }
Larry Hastings2f936352014-08-05 14:04:04 +10008683 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008684 if (buffer == NULL)
8685 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008686
8687 do {
8688 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008689 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008690 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008691 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008692 Py_END_ALLOW_THREADS
8693 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8694
Ross Lagerwall7807c352011-03-17 20:20:30 +02008695 if (n < 0) {
8696 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008697 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008698 }
Larry Hastings2f936352014-08-05 14:04:04 +10008699 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008700 _PyBytes_Resize(&buffer, n);
8701 return buffer;
8702}
Larry Hastings2f936352014-08-05 14:04:04 +10008703#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008704
Pablo Galindo4defba32018-01-27 16:16:37 +00008705#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8706/*[clinic input]
8707os.preadv -> Py_ssize_t
8708
8709 fd: int
8710 buffers: object
8711 offset: Py_off_t
8712 flags: int = 0
8713 /
8714
8715Reads from a file descriptor into a number of mutable bytes-like objects.
8716
8717Combines the functionality of readv() and pread(). As readv(), it will
8718transfer data into each buffer until it is full and then move on to the next
8719buffer in the sequence to hold the rest of the data. Its fourth argument,
8720specifies the file offset at which the input operation is to be performed. It
8721will return the total number of bytes read (which can be less than the total
8722capacity of all the objects).
8723
8724The flags argument contains a bitwise OR of zero or more of the following flags:
8725
8726- RWF_HIPRI
8727- RWF_NOWAIT
8728
8729Using non-zero flags requires Linux 4.6 or newer.
8730[clinic start generated code]*/
8731
8732static Py_ssize_t
8733os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8734 int flags)
8735/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8736{
8737 Py_ssize_t cnt, n;
8738 int async_err = 0;
8739 struct iovec *iov;
8740 Py_buffer *buf;
8741
8742 if (!PySequence_Check(buffers)) {
8743 PyErr_SetString(PyExc_TypeError,
8744 "preadv2() arg 2 must be a sequence");
8745 return -1;
8746 }
8747
8748 cnt = PySequence_Size(buffers);
8749 if (cnt < 0) {
8750 return -1;
8751 }
8752
8753#ifndef HAVE_PREADV2
8754 if(flags != 0) {
8755 argument_unavailable_error("preadv2", "flags");
8756 return -1;
8757 }
8758#endif
8759
8760 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8761 return -1;
8762 }
8763#ifdef HAVE_PREADV2
8764 do {
8765 Py_BEGIN_ALLOW_THREADS
8766 _Py_BEGIN_SUPPRESS_IPH
8767 n = preadv2(fd, iov, cnt, offset, flags);
8768 _Py_END_SUPPRESS_IPH
8769 Py_END_ALLOW_THREADS
8770 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8771#else
8772 do {
8773 Py_BEGIN_ALLOW_THREADS
8774 _Py_BEGIN_SUPPRESS_IPH
8775 n = preadv(fd, iov, cnt, offset);
8776 _Py_END_SUPPRESS_IPH
8777 Py_END_ALLOW_THREADS
8778 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8779#endif
8780
8781 iov_cleanup(iov, buf, cnt);
8782 if (n < 0) {
8783 if (!async_err) {
8784 posix_error();
8785 }
8786 return -1;
8787 }
8788
8789 return n;
8790}
8791#endif /* HAVE_PREADV */
8792
Larry Hastings2f936352014-08-05 14:04:04 +10008793
8794/*[clinic input]
8795os.write -> Py_ssize_t
8796
8797 fd: int
8798 data: Py_buffer
8799 /
8800
8801Write a bytes object to a file descriptor.
8802[clinic start generated code]*/
8803
Larry Hastings2f936352014-08-05 14:04:04 +10008804static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008805os_write_impl(PyObject *module, int fd, Py_buffer *data)
8806/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008807{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008808 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008809}
8810
8811#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008812PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008813"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008814sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008815 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008816Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008817
Larry Hastings2f936352014-08-05 14:04:04 +10008818/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008819static PyObject *
8820posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8821{
8822 int in, out;
8823 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008824 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008825 off_t offset;
8826
8827#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8828#ifndef __APPLE__
8829 Py_ssize_t len;
8830#endif
8831 PyObject *headers = NULL, *trailers = NULL;
8832 Py_buffer *hbuf, *tbuf;
8833 off_t sbytes;
8834 struct sf_hdtr sf;
8835 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008836 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008837 static char *keywords[] = {"out", "in",
8838 "offset", "count",
8839 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008840
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008841 sf.headers = NULL;
8842 sf.trailers = NULL;
8843
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008844#ifdef __APPLE__
8845 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008846 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008847#else
8848 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008849 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008850#endif
8851 &headers, &trailers, &flags))
8852 return NULL;
8853 if (headers != NULL) {
8854 if (!PySequence_Check(headers)) {
8855 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008856 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008857 return NULL;
8858 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008859 Py_ssize_t i = PySequence_Size(headers);
8860 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008861 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008862 if (i > INT_MAX) {
8863 PyErr_SetString(PyExc_OverflowError,
8864 "sendfile() header is too large");
8865 return NULL;
8866 }
8867 if (i > 0) {
8868 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008869 if (iov_setup(&(sf.headers), &hbuf,
8870 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008871 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008872#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008873 for (i = 0; i < sf.hdr_cnt; i++) {
8874 Py_ssize_t blen = sf.headers[i].iov_len;
8875# define OFF_T_MAX 0x7fffffffffffffff
8876 if (sbytes >= OFF_T_MAX - blen) {
8877 PyErr_SetString(PyExc_OverflowError,
8878 "sendfile() header is too large");
8879 return NULL;
8880 }
8881 sbytes += blen;
8882 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008883#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008884 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008885 }
8886 }
8887 if (trailers != NULL) {
8888 if (!PySequence_Check(trailers)) {
8889 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008890 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008891 return NULL;
8892 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008893 Py_ssize_t i = PySequence_Size(trailers);
8894 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008895 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008896 if (i > INT_MAX) {
8897 PyErr_SetString(PyExc_OverflowError,
8898 "sendfile() trailer is too large");
8899 return NULL;
8900 }
8901 if (i > 0) {
8902 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008903 if (iov_setup(&(sf.trailers), &tbuf,
8904 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008905 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008906 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008907 }
8908 }
8909
Steve Dower8fc89802015-04-12 00:26:27 -04008910 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008911 do {
8912 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008913#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008914 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008915#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008916 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008917#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008918 Py_END_ALLOW_THREADS
8919 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008920 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008921
8922 if (sf.headers != NULL)
8923 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8924 if (sf.trailers != NULL)
8925 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8926
8927 if (ret < 0) {
8928 if ((errno == EAGAIN) || (errno == EBUSY)) {
8929 if (sbytes != 0) {
8930 // some data has been sent
8931 goto done;
8932 }
8933 else {
8934 // no data has been sent; upper application is supposed
8935 // to retry on EAGAIN or EBUSY
8936 return posix_error();
8937 }
8938 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008939 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008940 }
8941 goto done;
8942
8943done:
8944 #if !defined(HAVE_LARGEFILE_SUPPORT)
8945 return Py_BuildValue("l", sbytes);
8946 #else
8947 return Py_BuildValue("L", sbytes);
8948 #endif
8949
8950#else
8951 Py_ssize_t count;
8952 PyObject *offobj;
8953 static char *keywords[] = {"out", "in",
8954 "offset", "count", NULL};
8955 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8956 keywords, &out, &in, &offobj, &count))
8957 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008958#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008959 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008960 do {
8961 Py_BEGIN_ALLOW_THREADS
8962 ret = sendfile(out, in, NULL, count);
8963 Py_END_ALLOW_THREADS
8964 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008965 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008966 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008967 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008968 }
8969#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008970 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008971 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008972
8973 do {
8974 Py_BEGIN_ALLOW_THREADS
8975 ret = sendfile(out, in, &offset, count);
8976 Py_END_ALLOW_THREADS
8977 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008978 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008979 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008980 return Py_BuildValue("n", ret);
8981#endif
8982}
Larry Hastings2f936352014-08-05 14:04:04 +10008983#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008984
Larry Hastings2f936352014-08-05 14:04:04 +10008985
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008986#if defined(__APPLE__)
8987/*[clinic input]
8988os._fcopyfile
8989
8990 infd: int
8991 outfd: int
8992 flags: int
8993 /
8994
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008995Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008996[clinic start generated code]*/
8997
8998static PyObject *
8999os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009000/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009001{
9002 int ret;
9003
9004 Py_BEGIN_ALLOW_THREADS
9005 ret = fcopyfile(infd, outfd, NULL, flags);
9006 Py_END_ALLOW_THREADS
9007 if (ret < 0)
9008 return posix_error();
9009 Py_RETURN_NONE;
9010}
9011#endif
9012
9013
Larry Hastings2f936352014-08-05 14:04:04 +10009014/*[clinic input]
9015os.fstat
9016
9017 fd : int
9018
9019Perform a stat system call on the given file descriptor.
9020
9021Like stat(), but for an open file descriptor.
9022Equivalent to os.stat(fd).
9023[clinic start generated code]*/
9024
Larry Hastings2f936352014-08-05 14:04:04 +10009025static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009026os_fstat_impl(PyObject *module, int fd)
9027/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009028{
Victor Stinner8c62be82010-05-06 00:08:46 +00009029 STRUCT_STAT st;
9030 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009031 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009032
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009033 do {
9034 Py_BEGIN_ALLOW_THREADS
9035 res = FSTAT(fd, &st);
9036 Py_END_ALLOW_THREADS
9037 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009038 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009039#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009040 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009041#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009042 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009043#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009044 }
Tim Peters5aa91602002-01-30 05:46:57 +00009045
Victor Stinner4195b5c2012-02-08 23:03:19 +01009046 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009047}
9048
Larry Hastings2f936352014-08-05 14:04:04 +10009049
9050/*[clinic input]
9051os.isatty -> bool
9052 fd: int
9053 /
9054
9055Return True if the fd is connected to a terminal.
9056
9057Return True if the file descriptor is an open file descriptor
9058connected to the slave end of a terminal.
9059[clinic start generated code]*/
9060
Larry Hastings2f936352014-08-05 14:04:04 +10009061static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009062os_isatty_impl(PyObject *module, int fd)
9063/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009064{
Steve Dower8fc89802015-04-12 00:26:27 -04009065 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009066 _Py_BEGIN_SUPPRESS_IPH
9067 return_value = isatty(fd);
9068 _Py_END_SUPPRESS_IPH
9069 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009070}
9071
9072
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009073#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009074/*[clinic input]
9075os.pipe
9076
9077Create a pipe.
9078
9079Returns a tuple of two file descriptors:
9080 (read_fd, write_fd)
9081[clinic start generated code]*/
9082
Larry Hastings2f936352014-08-05 14:04:04 +10009083static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009084os_pipe_impl(PyObject *module)
9085/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009086{
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009088#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009090 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009091 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009092#else
9093 int res;
9094#endif
9095
9096#ifdef MS_WINDOWS
9097 attr.nLength = sizeof(attr);
9098 attr.lpSecurityDescriptor = NULL;
9099 attr.bInheritHandle = FALSE;
9100
9101 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009102 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009103 ok = CreatePipe(&read, &write, &attr, 0);
9104 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009105 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9106 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009107 if (fds[0] == -1 || fds[1] == -1) {
9108 CloseHandle(read);
9109 CloseHandle(write);
9110 ok = 0;
9111 }
9112 }
Steve Dowerc3630612016-11-19 18:41:16 -08009113 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009114 Py_END_ALLOW_THREADS
9115
Victor Stinner8c62be82010-05-06 00:08:46 +00009116 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009117 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009118#else
9119
9120#ifdef HAVE_PIPE2
9121 Py_BEGIN_ALLOW_THREADS
9122 res = pipe2(fds, O_CLOEXEC);
9123 Py_END_ALLOW_THREADS
9124
9125 if (res != 0 && errno == ENOSYS)
9126 {
9127#endif
9128 Py_BEGIN_ALLOW_THREADS
9129 res = pipe(fds);
9130 Py_END_ALLOW_THREADS
9131
9132 if (res == 0) {
9133 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9134 close(fds[0]);
9135 close(fds[1]);
9136 return NULL;
9137 }
9138 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9139 close(fds[0]);
9140 close(fds[1]);
9141 return NULL;
9142 }
9143 }
9144#ifdef HAVE_PIPE2
9145 }
9146#endif
9147
9148 if (res != 0)
9149 return PyErr_SetFromErrno(PyExc_OSError);
9150#endif /* !MS_WINDOWS */
9151 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009152}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009153#endif /* HAVE_PIPE */
9154
Larry Hastings2f936352014-08-05 14:04:04 +10009155
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009156#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009157/*[clinic input]
9158os.pipe2
9159
9160 flags: int
9161 /
9162
9163Create a pipe with flags set atomically.
9164
9165Returns a tuple of two file descriptors:
9166 (read_fd, write_fd)
9167
9168flags can be constructed by ORing together one or more of these values:
9169O_NONBLOCK, O_CLOEXEC.
9170[clinic start generated code]*/
9171
Larry Hastings2f936352014-08-05 14:04:04 +10009172static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009173os_pipe2_impl(PyObject *module, int flags)
9174/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009175{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009176 int fds[2];
9177 int res;
9178
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009179 res = pipe2(fds, flags);
9180 if (res != 0)
9181 return posix_error();
9182 return Py_BuildValue("(ii)", fds[0], fds[1]);
9183}
9184#endif /* HAVE_PIPE2 */
9185
Larry Hastings2f936352014-08-05 14:04:04 +10009186
Ross Lagerwall7807c352011-03-17 20:20:30 +02009187#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009188/*[clinic input]
9189os.writev -> Py_ssize_t
9190 fd: int
9191 buffers: object
9192 /
9193
9194Iterate over buffers, and write the contents of each to a file descriptor.
9195
9196Returns the total number of bytes written.
9197buffers must be a sequence of bytes-like objects.
9198[clinic start generated code]*/
9199
Larry Hastings2f936352014-08-05 14:04:04 +10009200static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009201os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9202/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009203{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009204 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009205 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009206 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009207 struct iovec *iov;
9208 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009209
9210 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009211 PyErr_SetString(PyExc_TypeError,
9212 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009213 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009214 }
Larry Hastings2f936352014-08-05 14:04:04 +10009215 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009216 if (cnt < 0)
9217 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009218
Larry Hastings2f936352014-08-05 14:04:04 +10009219 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9220 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009221 }
9222
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009223 do {
9224 Py_BEGIN_ALLOW_THREADS
9225 result = writev(fd, iov, cnt);
9226 Py_END_ALLOW_THREADS
9227 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009228
9229 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009230 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009231 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009232
Georg Brandl306336b2012-06-24 12:55:33 +02009233 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009234}
Larry Hastings2f936352014-08-05 14:04:04 +10009235#endif /* HAVE_WRITEV */
9236
9237
9238#ifdef HAVE_PWRITE
9239/*[clinic input]
9240os.pwrite -> Py_ssize_t
9241
9242 fd: int
9243 buffer: Py_buffer
9244 offset: Py_off_t
9245 /
9246
9247Write bytes to a file descriptor starting at a particular offset.
9248
9249Write buffer to fd, starting at offset bytes from the beginning of
9250the file. Returns the number of bytes writte. Does not change the
9251current file offset.
9252[clinic start generated code]*/
9253
Larry Hastings2f936352014-08-05 14:04:04 +10009254static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009255os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9256/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009257{
9258 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009259 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009260
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009261 do {
9262 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009263 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009264 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009265 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009266 Py_END_ALLOW_THREADS
9267 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009268
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009269 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009270 posix_error();
9271 return size;
9272}
9273#endif /* HAVE_PWRITE */
9274
Pablo Galindo4defba32018-01-27 16:16:37 +00009275#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9276/*[clinic input]
9277os.pwritev -> Py_ssize_t
9278
9279 fd: int
9280 buffers: object
9281 offset: Py_off_t
9282 flags: int = 0
9283 /
9284
9285Writes the contents of bytes-like objects to a file descriptor at a given offset.
9286
9287Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9288of bytes-like objects. Buffers are processed in array order. Entire contents of first
9289buffer is written before proceeding to second, and so on. The operating system may
9290set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9291This function writes the contents of each object to the file descriptor and returns
9292the total number of bytes written.
9293
9294The flags argument contains a bitwise OR of zero or more of the following flags:
9295
9296- RWF_DSYNC
9297- RWF_SYNC
9298
9299Using non-zero flags requires Linux 4.7 or newer.
9300[clinic start generated code]*/
9301
9302static Py_ssize_t
9303os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9304 int flags)
9305/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9306{
9307 Py_ssize_t cnt;
9308 Py_ssize_t result;
9309 int async_err = 0;
9310 struct iovec *iov;
9311 Py_buffer *buf;
9312
9313 if (!PySequence_Check(buffers)) {
9314 PyErr_SetString(PyExc_TypeError,
9315 "pwritev() arg 2 must be a sequence");
9316 return -1;
9317 }
9318
9319 cnt = PySequence_Size(buffers);
9320 if (cnt < 0) {
9321 return -1;
9322 }
9323
9324#ifndef HAVE_PWRITEV2
9325 if(flags != 0) {
9326 argument_unavailable_error("pwritev2", "flags");
9327 return -1;
9328 }
9329#endif
9330
9331 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9332 return -1;
9333 }
9334#ifdef HAVE_PWRITEV2
9335 do {
9336 Py_BEGIN_ALLOW_THREADS
9337 _Py_BEGIN_SUPPRESS_IPH
9338 result = pwritev2(fd, iov, cnt, offset, flags);
9339 _Py_END_SUPPRESS_IPH
9340 Py_END_ALLOW_THREADS
9341 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9342#else
9343 do {
9344 Py_BEGIN_ALLOW_THREADS
9345 _Py_BEGIN_SUPPRESS_IPH
9346 result = pwritev(fd, iov, cnt, offset);
9347 _Py_END_SUPPRESS_IPH
9348 Py_END_ALLOW_THREADS
9349 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9350#endif
9351
9352 iov_cleanup(iov, buf, cnt);
9353 if (result < 0) {
9354 if (!async_err) {
9355 posix_error();
9356 }
9357 return -1;
9358 }
9359
9360 return result;
9361}
9362#endif /* HAVE_PWRITEV */
9363
9364
9365
Larry Hastings2f936352014-08-05 14:04:04 +10009366
9367#ifdef HAVE_MKFIFO
9368/*[clinic input]
9369os.mkfifo
9370
9371 path: path_t
9372 mode: int=0o666
9373 *
9374 dir_fd: dir_fd(requires='mkfifoat')=None
9375
9376Create a "fifo" (a POSIX named pipe).
9377
9378If dir_fd is not None, it should be a file descriptor open to a directory,
9379 and path should be relative; path will then be relative to that directory.
9380dir_fd may not be implemented on your platform.
9381 If it is unavailable, using it will raise a NotImplementedError.
9382[clinic start generated code]*/
9383
Larry Hastings2f936352014-08-05 14:04:04 +10009384static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009385os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9386/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009387{
9388 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009389 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009390
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009391 do {
9392 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009393#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009394 if (dir_fd != DEFAULT_DIR_FD)
9395 result = mkfifoat(dir_fd, path->narrow, mode);
9396 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009397#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009398 result = mkfifo(path->narrow, mode);
9399 Py_END_ALLOW_THREADS
9400 } while (result != 0 && errno == EINTR &&
9401 !(async_err = PyErr_CheckSignals()));
9402 if (result != 0)
9403 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009404
9405 Py_RETURN_NONE;
9406}
9407#endif /* HAVE_MKFIFO */
9408
9409
9410#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9411/*[clinic input]
9412os.mknod
9413
9414 path: path_t
9415 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009416 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009417 *
9418 dir_fd: dir_fd(requires='mknodat')=None
9419
9420Create a node in the file system.
9421
9422Create a node in the file system (file, device special file or named pipe)
9423at path. mode specifies both the permissions to use and the
9424type of node to be created, being combined (bitwise OR) with one of
9425S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9426device defines the newly created device special file (probably using
9427os.makedev()). Otherwise device is ignored.
9428
9429If dir_fd is not None, it should be a file descriptor open to a directory,
9430 and path should be relative; path will then be relative to that directory.
9431dir_fd may not be implemented on your platform.
9432 If it is unavailable, using it will raise a NotImplementedError.
9433[clinic start generated code]*/
9434
Larry Hastings2f936352014-08-05 14:04:04 +10009435static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009436os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009437 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009438/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009439{
9440 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009441 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009442
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009443 do {
9444 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009445#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009446 if (dir_fd != DEFAULT_DIR_FD)
9447 result = mknodat(dir_fd, path->narrow, mode, device);
9448 else
Larry Hastings2f936352014-08-05 14:04:04 +10009449#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009450 result = mknod(path->narrow, mode, device);
9451 Py_END_ALLOW_THREADS
9452 } while (result != 0 && errno == EINTR &&
9453 !(async_err = PyErr_CheckSignals()));
9454 if (result != 0)
9455 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009456
9457 Py_RETURN_NONE;
9458}
9459#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9460
9461
9462#ifdef HAVE_DEVICE_MACROS
9463/*[clinic input]
9464os.major -> unsigned_int
9465
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009466 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009467 /
9468
9469Extracts a device major number from a raw device number.
9470[clinic start generated code]*/
9471
Larry Hastings2f936352014-08-05 14:04:04 +10009472static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009473os_major_impl(PyObject *module, dev_t device)
9474/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009475{
9476 return major(device);
9477}
9478
9479
9480/*[clinic input]
9481os.minor -> unsigned_int
9482
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009483 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009484 /
9485
9486Extracts a device minor number from a raw device number.
9487[clinic start generated code]*/
9488
Larry Hastings2f936352014-08-05 14:04:04 +10009489static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009490os_minor_impl(PyObject *module, dev_t device)
9491/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009492{
9493 return minor(device);
9494}
9495
9496
9497/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009498os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009499
9500 major: int
9501 minor: int
9502 /
9503
9504Composes a raw device number from the major and minor device numbers.
9505[clinic start generated code]*/
9506
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009507static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009508os_makedev_impl(PyObject *module, int major, int minor)
9509/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009510{
9511 return makedev(major, minor);
9512}
9513#endif /* HAVE_DEVICE_MACROS */
9514
9515
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009516#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009517/*[clinic input]
9518os.ftruncate
9519
9520 fd: int
9521 length: Py_off_t
9522 /
9523
9524Truncate a file, specified by file descriptor, to a specific length.
9525[clinic start generated code]*/
9526
Larry Hastings2f936352014-08-05 14:04:04 +10009527static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009528os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9529/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009530{
9531 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009532 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009533
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009534 do {
9535 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009536 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009537#ifdef MS_WINDOWS
9538 result = _chsize_s(fd, length);
9539#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009540 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009541#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009542 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009543 Py_END_ALLOW_THREADS
9544 } while (result != 0 && errno == EINTR &&
9545 !(async_err = PyErr_CheckSignals()));
9546 if (result != 0)
9547 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009548 Py_RETURN_NONE;
9549}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009550#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009551
9552
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009553#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009554/*[clinic input]
9555os.truncate
9556 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9557 length: Py_off_t
9558
9559Truncate a file, specified by path, to a specific length.
9560
9561On some platforms, path may also be specified as an open file descriptor.
9562 If this functionality is unavailable, using it raises an exception.
9563[clinic start generated code]*/
9564
Larry Hastings2f936352014-08-05 14:04:04 +10009565static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009566os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9567/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009568{
9569 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009570#ifdef MS_WINDOWS
9571 int fd;
9572#endif
9573
9574 if (path->fd != -1)
9575 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009576
9577 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009578 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009579#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009580 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009581 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009582 result = -1;
9583 else {
9584 result = _chsize_s(fd, length);
9585 close(fd);
9586 if (result < 0)
9587 errno = result;
9588 }
9589#else
9590 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009591#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009592 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009593 Py_END_ALLOW_THREADS
9594 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009595 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009596
9597 Py_RETURN_NONE;
9598}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009599#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009600
Ross Lagerwall7807c352011-03-17 20:20:30 +02009601
Victor Stinnerd6b17692014-09-30 12:20:05 +02009602/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9603 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9604 defined, which is the case in Python on AIX. AIX bug report:
9605 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9606#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9607# define POSIX_FADVISE_AIX_BUG
9608#endif
9609
Victor Stinnerec39e262014-09-30 12:35:58 +02009610
Victor Stinnerd6b17692014-09-30 12:20:05 +02009611#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009612/*[clinic input]
9613os.posix_fallocate
9614
9615 fd: int
9616 offset: Py_off_t
9617 length: Py_off_t
9618 /
9619
9620Ensure a file has allocated at least a particular number of bytes on disk.
9621
9622Ensure that the file specified by fd encompasses a range of bytes
9623starting at offset bytes from the beginning and continuing for length bytes.
9624[clinic start generated code]*/
9625
Larry Hastings2f936352014-08-05 14:04:04 +10009626static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009627os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009628 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009629/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009630{
9631 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009632 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009633
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009634 do {
9635 Py_BEGIN_ALLOW_THREADS
9636 result = posix_fallocate(fd, offset, length);
9637 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009638 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9639
9640 if (result == 0)
9641 Py_RETURN_NONE;
9642
9643 if (async_err)
9644 return NULL;
9645
9646 errno = result;
9647 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009648}
Victor Stinnerec39e262014-09-30 12:35:58 +02009649#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009650
Ross Lagerwall7807c352011-03-17 20:20:30 +02009651
Victor Stinnerd6b17692014-09-30 12:20:05 +02009652#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009653/*[clinic input]
9654os.posix_fadvise
9655
9656 fd: int
9657 offset: Py_off_t
9658 length: Py_off_t
9659 advice: int
9660 /
9661
9662Announce an intention to access data in a specific pattern.
9663
9664Announce an intention to access data in a specific pattern, thus allowing
9665the kernel to make optimizations.
9666The advice applies to the region of the file specified by fd starting at
9667offset and continuing for length bytes.
9668advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9669POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9670POSIX_FADV_DONTNEED.
9671[clinic start generated code]*/
9672
Larry Hastings2f936352014-08-05 14:04:04 +10009673static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009674os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009675 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009676/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009677{
9678 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009679 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009680
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009681 do {
9682 Py_BEGIN_ALLOW_THREADS
9683 result = posix_fadvise(fd, offset, length, advice);
9684 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009685 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9686
9687 if (result == 0)
9688 Py_RETURN_NONE;
9689
9690 if (async_err)
9691 return NULL;
9692
9693 errno = result;
9694 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009695}
Victor Stinnerec39e262014-09-30 12:35:58 +02009696#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009697
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009698#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009699
Fred Drake762e2061999-08-26 17:23:54 +00009700/* Save putenv() parameters as values here, so we can collect them when they
9701 * get re-set with another call for the same key. */
9702static PyObject *posix_putenv_garbage;
9703
Larry Hastings2f936352014-08-05 14:04:04 +10009704static void
9705posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009706{
Larry Hastings2f936352014-08-05 14:04:04 +10009707 /* Install the first arg and newstr in posix_putenv_garbage;
9708 * this will cause previous value to be collected. This has to
9709 * happen after the real putenv() call because the old value
9710 * was still accessible until then. */
9711 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9712 /* really not much we can do; just leak */
9713 PyErr_Clear();
9714 else
9715 Py_DECREF(value);
9716}
9717
9718
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009719#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009720/*[clinic input]
9721os.putenv
9722
9723 name: unicode
9724 value: unicode
9725 /
9726
9727Change or add an environment variable.
9728[clinic start generated code]*/
9729
Larry Hastings2f936352014-08-05 14:04:04 +10009730static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009731os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9732/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009733{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009734 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009735 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009736
Serhiy Storchaka77703942017-06-25 07:33:01 +03009737 /* Search from index 1 because on Windows starting '=' is allowed for
9738 defining hidden environment variables. */
9739 if (PyUnicode_GET_LENGTH(name) == 0 ||
9740 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9741 {
9742 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9743 return NULL;
9744 }
Larry Hastings2f936352014-08-05 14:04:04 +10009745 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9746 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009747 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009748 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009749
9750 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9751 if (env == NULL)
9752 goto error;
9753 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009754 PyErr_Format(PyExc_ValueError,
9755 "the environment variable is longer than %u characters",
9756 _MAX_ENV);
9757 goto error;
9758 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009759 if (wcslen(env) != (size_t)size) {
9760 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009761 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009762 }
9763
Larry Hastings2f936352014-08-05 14:04:04 +10009764 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009766 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009768
Larry Hastings2f936352014-08-05 14:04:04 +10009769 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009770 Py_RETURN_NONE;
9771
9772error:
Larry Hastings2f936352014-08-05 14:04:04 +10009773 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009774 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009775}
Larry Hastings2f936352014-08-05 14:04:04 +10009776#else /* MS_WINDOWS */
9777/*[clinic input]
9778os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009779
Larry Hastings2f936352014-08-05 14:04:04 +10009780 name: FSConverter
9781 value: FSConverter
9782 /
9783
9784Change or add an environment variable.
9785[clinic start generated code]*/
9786
Larry Hastings2f936352014-08-05 14:04:04 +10009787static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009788os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9789/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009790{
9791 PyObject *bytes = NULL;
9792 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009793 const char *name_string = PyBytes_AS_STRING(name);
9794 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009795
Serhiy Storchaka77703942017-06-25 07:33:01 +03009796 if (strchr(name_string, '=') != NULL) {
9797 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9798 return NULL;
9799 }
Larry Hastings2f936352014-08-05 14:04:04 +10009800 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9801 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009802 return NULL;
9803 }
9804
9805 env = PyBytes_AS_STRING(bytes);
9806 if (putenv(env)) {
9807 Py_DECREF(bytes);
9808 return posix_error();
9809 }
9810
9811 posix_putenv_garbage_setitem(name, bytes);
9812 Py_RETURN_NONE;
9813}
9814#endif /* MS_WINDOWS */
9815#endif /* HAVE_PUTENV */
9816
9817
9818#ifdef HAVE_UNSETENV
9819/*[clinic input]
9820os.unsetenv
9821 name: FSConverter
9822 /
9823
9824Delete an environment variable.
9825[clinic start generated code]*/
9826
Larry Hastings2f936352014-08-05 14:04:04 +10009827static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009828os_unsetenv_impl(PyObject *module, PyObject *name)
9829/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009830{
Victor Stinner984890f2011-11-24 13:53:38 +01009831#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009832 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009833#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009834
Victor Stinner984890f2011-11-24 13:53:38 +01009835#ifdef HAVE_BROKEN_UNSETENV
9836 unsetenv(PyBytes_AS_STRING(name));
9837#else
Victor Stinner65170952011-11-22 22:16:17 +01009838 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009839 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009840 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009841#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009842
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 /* Remove the key from posix_putenv_garbage;
9844 * this will cause it to be collected. This has to
9845 * happen after the real unsetenv() call because the
9846 * old value was still accessible until then.
9847 */
Victor Stinner65170952011-11-22 22:16:17 +01009848 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 /* really not much we can do; just leak */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02009850 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
9851 return NULL;
9852 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 PyErr_Clear();
9854 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009855 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009856}
Larry Hastings2f936352014-08-05 14:04:04 +10009857#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009858
Larry Hastings2f936352014-08-05 14:04:04 +10009859
9860/*[clinic input]
9861os.strerror
9862
9863 code: int
9864 /
9865
9866Translate an error code to a message string.
9867[clinic start generated code]*/
9868
Larry Hastings2f936352014-08-05 14:04:04 +10009869static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009870os_strerror_impl(PyObject *module, int code)
9871/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009872{
9873 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 if (message == NULL) {
9875 PyErr_SetString(PyExc_ValueError,
9876 "strerror() argument out of range");
9877 return NULL;
9878 }
Victor Stinner1b579672011-12-17 05:47:23 +01009879 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009880}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009881
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009882
Guido van Rossumc9641791998-08-04 15:26:23 +00009883#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009884#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009885/*[clinic input]
9886os.WCOREDUMP -> bool
9887
9888 status: int
9889 /
9890
9891Return True if the process returning status was dumped to a core file.
9892[clinic start generated code]*/
9893
Larry Hastings2f936352014-08-05 14:04:04 +10009894static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009895os_WCOREDUMP_impl(PyObject *module, int status)
9896/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009897{
9898 WAIT_TYPE wait_status;
9899 WAIT_STATUS_INT(wait_status) = status;
9900 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009901}
9902#endif /* WCOREDUMP */
9903
Larry Hastings2f936352014-08-05 14:04:04 +10009904
Fred Drake106c1a02002-04-23 15:58:02 +00009905#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009906/*[clinic input]
9907os.WIFCONTINUED -> bool
9908
9909 status: int
9910
9911Return True if a particular process was continued from a job control stop.
9912
9913Return True if the process returning status was continued from a
9914job control stop.
9915[clinic start generated code]*/
9916
Larry Hastings2f936352014-08-05 14:04:04 +10009917static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009918os_WIFCONTINUED_impl(PyObject *module, int status)
9919/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009920{
9921 WAIT_TYPE wait_status;
9922 WAIT_STATUS_INT(wait_status) = status;
9923 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009924}
9925#endif /* WIFCONTINUED */
9926
Larry Hastings2f936352014-08-05 14:04:04 +10009927
Guido van Rossumc9641791998-08-04 15:26:23 +00009928#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009929/*[clinic input]
9930os.WIFSTOPPED -> bool
9931
9932 status: int
9933
9934Return True if the process returning status was stopped.
9935[clinic start generated code]*/
9936
Larry Hastings2f936352014-08-05 14:04:04 +10009937static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009938os_WIFSTOPPED_impl(PyObject *module, int status)
9939/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009940{
9941 WAIT_TYPE wait_status;
9942 WAIT_STATUS_INT(wait_status) = status;
9943 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009944}
9945#endif /* WIFSTOPPED */
9946
Larry Hastings2f936352014-08-05 14:04:04 +10009947
Guido van Rossumc9641791998-08-04 15:26:23 +00009948#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009949/*[clinic input]
9950os.WIFSIGNALED -> bool
9951
9952 status: int
9953
9954Return True if the process returning status was terminated by a signal.
9955[clinic start generated code]*/
9956
Larry Hastings2f936352014-08-05 14:04:04 +10009957static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009958os_WIFSIGNALED_impl(PyObject *module, int status)
9959/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009960{
9961 WAIT_TYPE wait_status;
9962 WAIT_STATUS_INT(wait_status) = status;
9963 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009964}
9965#endif /* WIFSIGNALED */
9966
Larry Hastings2f936352014-08-05 14:04:04 +10009967
Guido van Rossumc9641791998-08-04 15:26:23 +00009968#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009969/*[clinic input]
9970os.WIFEXITED -> bool
9971
9972 status: int
9973
9974Return True if the process returning status exited via the exit() system call.
9975[clinic start generated code]*/
9976
Larry Hastings2f936352014-08-05 14:04:04 +10009977static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009978os_WIFEXITED_impl(PyObject *module, int status)
9979/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009980{
9981 WAIT_TYPE wait_status;
9982 WAIT_STATUS_INT(wait_status) = status;
9983 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009984}
9985#endif /* WIFEXITED */
9986
Larry Hastings2f936352014-08-05 14:04:04 +10009987
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009988#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009989/*[clinic input]
9990os.WEXITSTATUS -> int
9991
9992 status: int
9993
9994Return the process return code from status.
9995[clinic start generated code]*/
9996
Larry Hastings2f936352014-08-05 14:04:04 +10009997static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009998os_WEXITSTATUS_impl(PyObject *module, int status)
9999/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010000{
10001 WAIT_TYPE wait_status;
10002 WAIT_STATUS_INT(wait_status) = status;
10003 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010004}
10005#endif /* WEXITSTATUS */
10006
Larry Hastings2f936352014-08-05 14:04:04 +100010007
Guido van Rossumc9641791998-08-04 15:26:23 +000010008#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010009/*[clinic input]
10010os.WTERMSIG -> int
10011
10012 status: int
10013
10014Return the signal that terminated the process that provided the status value.
10015[clinic start generated code]*/
10016
Larry Hastings2f936352014-08-05 14:04:04 +100010017static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010018os_WTERMSIG_impl(PyObject *module, int status)
10019/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010020{
10021 WAIT_TYPE wait_status;
10022 WAIT_STATUS_INT(wait_status) = status;
10023 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010024}
10025#endif /* WTERMSIG */
10026
Larry Hastings2f936352014-08-05 14:04:04 +100010027
Guido van Rossumc9641791998-08-04 15:26:23 +000010028#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010029/*[clinic input]
10030os.WSTOPSIG -> int
10031
10032 status: int
10033
10034Return the signal that stopped the process that provided the status value.
10035[clinic start generated code]*/
10036
Larry Hastings2f936352014-08-05 14:04:04 +100010037static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010038os_WSTOPSIG_impl(PyObject *module, int status)
10039/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010040{
10041 WAIT_TYPE wait_status;
10042 WAIT_STATUS_INT(wait_status) = status;
10043 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010044}
10045#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010046#endif /* HAVE_SYS_WAIT_H */
10047
10048
Thomas Wouters477c8d52006-05-27 19:21:47 +000010049#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010050#ifdef _SCO_DS
10051/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10052 needed definitions in sys/statvfs.h */
10053#define _SVID3
10054#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010055#include <sys/statvfs.h>
10056
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010057static PyObject*
10058_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -080010059 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 if (v == NULL)
10061 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010062
10063#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10065 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10066 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10067 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10068 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10069 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10070 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10071 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10072 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10073 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010074#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10076 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10077 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010078 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010080 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010082 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010084 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010086 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010088 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10090 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010091#endif
Michael Felt502d5512018-01-05 13:01:58 +010010092/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10093 * (issue #32390). */
10094#if defined(_AIX) && defined(_ALL_SOURCE)
10095 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10096#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010097 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010098#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010099 if (PyErr_Occurred()) {
10100 Py_DECREF(v);
10101 return NULL;
10102 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010103
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010105}
10106
Larry Hastings2f936352014-08-05 14:04:04 +100010107
10108/*[clinic input]
10109os.fstatvfs
10110 fd: int
10111 /
10112
10113Perform an fstatvfs system call on the given fd.
10114
10115Equivalent to statvfs(fd).
10116[clinic start generated code]*/
10117
Larry Hastings2f936352014-08-05 14:04:04 +100010118static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010119os_fstatvfs_impl(PyObject *module, int fd)
10120/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010121{
10122 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010123 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010125
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010126 do {
10127 Py_BEGIN_ALLOW_THREADS
10128 result = fstatvfs(fd, &st);
10129 Py_END_ALLOW_THREADS
10130 } while (result != 0 && errno == EINTR &&
10131 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010132 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010133 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010134
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010136}
Larry Hastings2f936352014-08-05 14:04:04 +100010137#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010138
10139
Thomas Wouters477c8d52006-05-27 19:21:47 +000010140#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010141#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010142/*[clinic input]
10143os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010144
Larry Hastings2f936352014-08-05 14:04:04 +100010145 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10146
10147Perform a statvfs system call on the given path.
10148
10149path may always be specified as a string.
10150On some platforms, path may also be specified as an open file descriptor.
10151 If this functionality is unavailable, using it raises an exception.
10152[clinic start generated code]*/
10153
Larry Hastings2f936352014-08-05 14:04:04 +100010154static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010155os_statvfs_impl(PyObject *module, path_t *path)
10156/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010157{
10158 int result;
10159 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010160
10161 Py_BEGIN_ALLOW_THREADS
10162#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010163 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010164#ifdef __APPLE__
10165 /* handle weak-linking on Mac OS X 10.3 */
10166 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010167 fd_specified("statvfs", path->fd);
10168 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010169 }
10170#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010171 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010172 }
10173 else
10174#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010175 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010176 Py_END_ALLOW_THREADS
10177
10178 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010179 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010180 }
10181
Larry Hastings2f936352014-08-05 14:04:04 +100010182 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010183}
Larry Hastings2f936352014-08-05 14:04:04 +100010184#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10185
Guido van Rossum94f6f721999-01-06 18:42:14 +000010186
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010187#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010188/*[clinic input]
10189os._getdiskusage
10190
Steve Dower23ad6d02018-02-22 10:39:10 -080010191 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010192
10193Return disk usage statistics about the given path as a (total, free) tuple.
10194[clinic start generated code]*/
10195
Larry Hastings2f936352014-08-05 14:04:04 +100010196static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010197os__getdiskusage_impl(PyObject *module, path_t *path)
10198/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010199{
10200 BOOL retval;
10201 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010202 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010203
10204 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010205 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010206 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010207 if (retval == 0) {
10208 if (GetLastError() == ERROR_DIRECTORY) {
10209 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010210
Joe Pamerc8c02492018-09-25 10:57:36 -040010211 dir_path = PyMem_New(wchar_t, path->length + 1);
10212 if (dir_path == NULL) {
10213 return PyErr_NoMemory();
10214 }
10215
10216 wcscpy_s(dir_path, path->length + 1, path->wide);
10217
10218 if (_dirnameW(dir_path) != -1) {
10219 Py_BEGIN_ALLOW_THREADS
10220 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10221 Py_END_ALLOW_THREADS
10222 }
10223 /* Record the last error in case it's modified by PyMem_Free. */
10224 err = GetLastError();
10225 PyMem_Free(dir_path);
10226 if (retval) {
10227 goto success;
10228 }
10229 }
10230 return PyErr_SetFromWindowsErr(err);
10231 }
10232
10233success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010234 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10235}
Larry Hastings2f936352014-08-05 14:04:04 +100010236#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010237
10238
Fred Drakec9680921999-12-13 16:37:25 +000010239/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10240 * It maps strings representing configuration variable names to
10241 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010242 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010243 * rarely-used constants. There are three separate tables that use
10244 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010245 *
10246 * This code is always included, even if none of the interfaces that
10247 * need it are included. The #if hackery needed to avoid it would be
10248 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010249 */
10250struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010251 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010252 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010253};
10254
Fred Drake12c6e2d1999-12-14 21:25:03 +000010255static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010256conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010257 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010258{
Christian Heimes217cfd12007-12-02 14:31:20 +000010259 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010260 int value = _PyLong_AsInt(arg);
10261 if (value == -1 && PyErr_Occurred())
10262 return 0;
10263 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010264 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010265 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010266 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010267 /* look up the value in the table using a binary search */
10268 size_t lo = 0;
10269 size_t mid;
10270 size_t hi = tablesize;
10271 int cmp;
10272 const char *confname;
10273 if (!PyUnicode_Check(arg)) {
10274 PyErr_SetString(PyExc_TypeError,
10275 "configuration names must be strings or integers");
10276 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010278 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010279 if (confname == NULL)
10280 return 0;
10281 while (lo < hi) {
10282 mid = (lo + hi) / 2;
10283 cmp = strcmp(confname, table[mid].name);
10284 if (cmp < 0)
10285 hi = mid;
10286 else if (cmp > 0)
10287 lo = mid + 1;
10288 else {
10289 *valuep = table[mid].value;
10290 return 1;
10291 }
10292 }
10293 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10294 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010296}
10297
10298
10299#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10300static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010301#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010303#endif
10304#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010306#endif
Fred Drakec9680921999-12-13 16:37:25 +000010307#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
10310#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
10319#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010321#endif
10322#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
10331#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010333#endif
10334#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
10340#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010342#endif
10343#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
10349#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010351#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010352#ifdef _PC_ACL_ENABLED
10353 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10354#endif
10355#ifdef _PC_MIN_HOLE_SIZE
10356 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10357#endif
10358#ifdef _PC_ALLOC_SIZE_MIN
10359 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10360#endif
10361#ifdef _PC_REC_INCR_XFER_SIZE
10362 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10363#endif
10364#ifdef _PC_REC_MAX_XFER_SIZE
10365 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10366#endif
10367#ifdef _PC_REC_MIN_XFER_SIZE
10368 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10369#endif
10370#ifdef _PC_REC_XFER_ALIGN
10371 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10372#endif
10373#ifdef _PC_SYMLINK_MAX
10374 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10375#endif
10376#ifdef _PC_XATTR_ENABLED
10377 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10378#endif
10379#ifdef _PC_XATTR_EXISTS
10380 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10381#endif
10382#ifdef _PC_TIMESTAMP_RESOLUTION
10383 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10384#endif
Fred Drakec9680921999-12-13 16:37:25 +000010385};
10386
Fred Drakec9680921999-12-13 16:37:25 +000010387static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010388conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010389{
10390 return conv_confname(arg, valuep, posix_constants_pathconf,
10391 sizeof(posix_constants_pathconf)
10392 / sizeof(struct constdef));
10393}
10394#endif
10395
Larry Hastings2f936352014-08-05 14:04:04 +100010396
Fred Drakec9680921999-12-13 16:37:25 +000010397#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010398/*[clinic input]
10399os.fpathconf -> long
10400
10401 fd: int
10402 name: path_confname
10403 /
10404
10405Return the configuration limit name for the file descriptor fd.
10406
10407If there is no limit, return -1.
10408[clinic start generated code]*/
10409
Larry Hastings2f936352014-08-05 14:04:04 +100010410static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010411os_fpathconf_impl(PyObject *module, int fd, int name)
10412/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010413{
10414 long limit;
10415
10416 errno = 0;
10417 limit = fpathconf(fd, name);
10418 if (limit == -1 && errno != 0)
10419 posix_error();
10420
10421 return limit;
10422}
10423#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010424
10425
10426#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010427/*[clinic input]
10428os.pathconf -> long
10429 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10430 name: path_confname
10431
10432Return the configuration limit name for the file or directory path.
10433
10434If there is no limit, return -1.
10435On some platforms, path may also be specified as an open file descriptor.
10436 If this functionality is unavailable, using it raises an exception.
10437[clinic start generated code]*/
10438
Larry Hastings2f936352014-08-05 14:04:04 +100010439static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010440os_pathconf_impl(PyObject *module, path_t *path, int name)
10441/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010442{
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010444
Victor Stinner8c62be82010-05-06 00:08:46 +000010445 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010446#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010447 if (path->fd != -1)
10448 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010449 else
10450#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010451 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 if (limit == -1 && errno != 0) {
10453 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010454 /* could be a path or name problem */
10455 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010456 else
Larry Hastings2f936352014-08-05 14:04:04 +100010457 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 }
Larry Hastings2f936352014-08-05 14:04:04 +100010459
10460 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010461}
Larry Hastings2f936352014-08-05 14:04:04 +100010462#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010463
10464#ifdef HAVE_CONFSTR
10465static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010466#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010468#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010469#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010471#endif
10472#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010474#endif
Fred Draked86ed291999-12-15 15:34:33 +000010475#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010477#endif
10478#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010480#endif
10481#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010483#endif
10484#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010486#endif
Fred Drakec9680921999-12-13 16:37:25 +000010487#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010489#endif
10490#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010492#endif
10493#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010494 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010495#endif
10496#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010498#endif
10499#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010501#endif
10502#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010504#endif
10505#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010506 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010507#endif
10508#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010510#endif
Fred Draked86ed291999-12-15 15:34:33 +000010511#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010513#endif
Fred Drakec9680921999-12-13 16:37:25 +000010514#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010515 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010516#endif
Fred Draked86ed291999-12-15 15:34:33 +000010517#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010518 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010519#endif
10520#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010522#endif
10523#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010525#endif
10526#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010528#endif
Fred Drakec9680921999-12-13 16:37:25 +000010529#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010530 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010531#endif
10532#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010533 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010534#endif
10535#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010536 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010537#endif
10538#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010540#endif
10541#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010543#endif
10544#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010546#endif
10547#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010549#endif
10550#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010552#endif
10553#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010555#endif
10556#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010558#endif
10559#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010560 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010561#endif
10562#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010564#endif
10565#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010567#endif
10568#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010569 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010570#endif
10571#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010572 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010573#endif
10574#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010576#endif
Fred Draked86ed291999-12-15 15:34:33 +000010577#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010579#endif
10580#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010582#endif
10583#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010585#endif
10586#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010587 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010588#endif
10589#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010590 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010591#endif
10592#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010593 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010594#endif
10595#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010596 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010597#endif
10598#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010600#endif
10601#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010603#endif
10604#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010606#endif
10607#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010608 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010609#endif
10610#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010611 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010612#endif
10613#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010614 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010615#endif
Fred Drakec9680921999-12-13 16:37:25 +000010616};
10617
10618static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010619conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010620{
10621 return conv_confname(arg, valuep, posix_constants_confstr,
10622 sizeof(posix_constants_confstr)
10623 / sizeof(struct constdef));
10624}
10625
Larry Hastings2f936352014-08-05 14:04:04 +100010626
10627/*[clinic input]
10628os.confstr
10629
10630 name: confstr_confname
10631 /
10632
10633Return a string-valued system configuration variable.
10634[clinic start generated code]*/
10635
Larry Hastings2f936352014-08-05 14:04:04 +100010636static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010637os_confstr_impl(PyObject *module, int name)
10638/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010639{
10640 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010641 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010642 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010643
Victor Stinnercb043522010-09-10 23:49:04 +000010644 errno = 0;
10645 len = confstr(name, buffer, sizeof(buffer));
10646 if (len == 0) {
10647 if (errno) {
10648 posix_error();
10649 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010650 }
10651 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010652 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010653 }
10654 }
Victor Stinnercb043522010-09-10 23:49:04 +000010655
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010656 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010657 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010658 char *buf = PyMem_Malloc(len);
10659 if (buf == NULL)
10660 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010661 len2 = confstr(name, buf, len);
10662 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010663 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010664 PyMem_Free(buf);
10665 }
10666 else
10667 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010668 return result;
10669}
Larry Hastings2f936352014-08-05 14:04:04 +100010670#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010671
10672
10673#ifdef HAVE_SYSCONF
10674static struct constdef posix_constants_sysconf[] = {
10675#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010677#endif
10678#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010680#endif
10681#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010682 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010683#endif
10684#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010686#endif
10687#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010688 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010689#endif
10690#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010691 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010692#endif
10693#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010694 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010695#endif
10696#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010697 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010698#endif
10699#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010701#endif
10702#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010703 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010704#endif
Fred Draked86ed291999-12-15 15:34:33 +000010705#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010707#endif
10708#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010710#endif
Fred Drakec9680921999-12-13 16:37:25 +000010711#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010713#endif
Fred Drakec9680921999-12-13 16:37:25 +000010714#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010715 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010716#endif
10717#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010719#endif
10720#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010722#endif
10723#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010724 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010725#endif
10726#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010727 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010728#endif
Fred Draked86ed291999-12-15 15:34:33 +000010729#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010730 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010731#endif
Fred Drakec9680921999-12-13 16:37:25 +000010732#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010733 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010734#endif
10735#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010736 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010737#endif
10738#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010740#endif
10741#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010742 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010743#endif
10744#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010745 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010746#endif
Fred Draked86ed291999-12-15 15:34:33 +000010747#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010749#endif
Fred Drakec9680921999-12-13 16:37:25 +000010750#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010751 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010752#endif
10753#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010754 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010755#endif
10756#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010757 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010758#endif
10759#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010760 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010761#endif
10762#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010764#endif
10765#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010766 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010767#endif
10768#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010769 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010770#endif
10771#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010773#endif
10774#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010775 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010776#endif
10777#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010779#endif
10780#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010782#endif
10783#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010785#endif
10786#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010788#endif
10789#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010791#endif
10792#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010794#endif
10795#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010797#endif
10798#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010800#endif
10801#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010803#endif
10804#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010806#endif
10807#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010809#endif
10810#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010812#endif
10813#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010815#endif
10816#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010818#endif
Fred Draked86ed291999-12-15 15:34:33 +000010819#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010821#endif
Fred Drakec9680921999-12-13 16:37:25 +000010822#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010824#endif
10825#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010827#endif
10828#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010829 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010830#endif
Fred Draked86ed291999-12-15 15:34:33 +000010831#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010832 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010833#endif
Fred Drakec9680921999-12-13 16:37:25 +000010834#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010836#endif
Fred Draked86ed291999-12-15 15:34:33 +000010837#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010839#endif
10840#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010842#endif
Fred Drakec9680921999-12-13 16:37:25 +000010843#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010845#endif
10846#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010848#endif
10849#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010851#endif
10852#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010854#endif
Fred Draked86ed291999-12-15 15:34:33 +000010855#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010857#endif
Fred Drakec9680921999-12-13 16:37:25 +000010858#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010859 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010860#endif
10861#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010862 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010863#endif
10864#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010866#endif
10867#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010868 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010869#endif
10870#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010872#endif
10873#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010874 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010875#endif
10876#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010877 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010878#endif
Fred Draked86ed291999-12-15 15:34:33 +000010879#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010880 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010881#endif
Fred Drakec9680921999-12-13 16:37:25 +000010882#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010884#endif
10885#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010886 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010887#endif
Fred Draked86ed291999-12-15 15:34:33 +000010888#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010890#endif
Fred Drakec9680921999-12-13 16:37:25 +000010891#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010892 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010893#endif
10894#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010896#endif
10897#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010899#endif
10900#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010901 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010902#endif
10903#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010905#endif
10906#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010908#endif
10909#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010910 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010911#endif
10912#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010914#endif
10915#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010917#endif
Fred Draked86ed291999-12-15 15:34:33 +000010918#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010920#endif
10921#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010923#endif
Fred Drakec9680921999-12-13 16:37:25 +000010924#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010925 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010926#endif
10927#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010928 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010929#endif
10930#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010931 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010932#endif
10933#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010934 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010935#endif
10936#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010937 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010938#endif
10939#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010940 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010941#endif
10942#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010943 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010944#endif
10945#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010946 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010947#endif
10948#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010949 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010950#endif
10951#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010952 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010953#endif
10954#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010955 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010956#endif
10957#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010958 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010959#endif
10960#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010961 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010962#endif
10963#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010964 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010965#endif
10966#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010967 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010968#endif
10969#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010971#endif
10972#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010973 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010974#endif
10975#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010977#endif
10978#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010980#endif
10981#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010983#endif
10984#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010985 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010986#endif
10987#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010988 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010989#endif
10990#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010991 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010992#endif
10993#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010994 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010995#endif
10996#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010997 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010998#endif
10999#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011000 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011001#endif
11002#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011003 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011004#endif
11005#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011006 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011007#endif
11008#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011009 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011010#endif
11011#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011012 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011013#endif
11014#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011015 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011016#endif
11017#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011018 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011019#endif
11020#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011021 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011022#endif
11023#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011024 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011025#endif
11026#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011027 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011028#endif
Fred Draked86ed291999-12-15 15:34:33 +000011029#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011030 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011031#endif
Fred Drakec9680921999-12-13 16:37:25 +000011032#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011033 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011034#endif
11035#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011036 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011037#endif
11038#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011039 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011040#endif
11041#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011042 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011043#endif
11044#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011045 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011046#endif
11047#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011048 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011049#endif
11050#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011051 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011052#endif
11053#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011054 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011055#endif
11056#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011057 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011058#endif
11059#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011060 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011061#endif
11062#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011063 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011064#endif
11065#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011066 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011067#endif
11068#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011069 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011070#endif
11071#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011072 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011073#endif
11074#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011075 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011076#endif
11077#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011078 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011079#endif
11080#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011081 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011082#endif
11083#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011084 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011085#endif
11086#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011087 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011088#endif
11089#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011090 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011091#endif
11092#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011093 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011094#endif
11095#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011096 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011097#endif
11098#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011099 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011100#endif
11101#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011102 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011103#endif
11104#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011105 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011106#endif
11107#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011108 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011109#endif
11110#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011111 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011112#endif
11113#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011114 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011115#endif
11116#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011117 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011118#endif
11119#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011120 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011121#endif
11122#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011123 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011124#endif
11125#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011126 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011127#endif
11128#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011129 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011130#endif
11131#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011132 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011133#endif
11134#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011135 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011136#endif
11137#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011138 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011139#endif
11140#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011141 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011142#endif
11143#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011144 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011145#endif
11146#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011147 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011148#endif
11149#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011150 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011151#endif
11152#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011153 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011154#endif
11155#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011156 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011157#endif
11158#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011159 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011160#endif
11161#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011162 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011163#endif
11164#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011165 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011166#endif
11167};
11168
11169static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011170conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011171{
11172 return conv_confname(arg, valuep, posix_constants_sysconf,
11173 sizeof(posix_constants_sysconf)
11174 / sizeof(struct constdef));
11175}
11176
Larry Hastings2f936352014-08-05 14:04:04 +100011177
11178/*[clinic input]
11179os.sysconf -> long
11180 name: sysconf_confname
11181 /
11182
11183Return an integer-valued system configuration variable.
11184[clinic start generated code]*/
11185
Larry Hastings2f936352014-08-05 14:04:04 +100011186static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011187os_sysconf_impl(PyObject *module, int name)
11188/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011189{
11190 long value;
11191
11192 errno = 0;
11193 value = sysconf(name);
11194 if (value == -1 && errno != 0)
11195 posix_error();
11196 return value;
11197}
11198#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011199
11200
Fred Drakebec628d1999-12-15 18:31:10 +000011201/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011202 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011203 * the exported dictionaries that are used to publish information about the
11204 * names available on the host platform.
11205 *
11206 * Sorting the table at runtime ensures that the table is properly ordered
11207 * when used, even for platforms we're not able to test on. It also makes
11208 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011209 */
Fred Drakebec628d1999-12-15 18:31:10 +000011210
11211static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011212cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011213{
11214 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011215 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011216 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011218
11219 return strcmp(c1->name, c2->name);
11220}
11221
11222static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011223setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011224 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011225{
Fred Drakebec628d1999-12-15 18:31:10 +000011226 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011227 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011228
11229 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11230 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011231 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011233
Barry Warsaw3155db32000-04-13 15:20:40 +000011234 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 PyObject *o = PyLong_FromLong(table[i].value);
11236 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11237 Py_XDECREF(o);
11238 Py_DECREF(d);
11239 return -1;
11240 }
11241 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011242 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011243 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011244}
11245
Fred Drakebec628d1999-12-15 18:31:10 +000011246/* Return -1 on failure, 0 on success. */
11247static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011248setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011249{
11250#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011251 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011252 sizeof(posix_constants_pathconf)
11253 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011254 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011255 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011256#endif
11257#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011258 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011259 sizeof(posix_constants_confstr)
11260 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011261 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011262 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011263#endif
11264#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011265 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011266 sizeof(posix_constants_sysconf)
11267 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011268 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011269 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011270#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011271 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011272}
Fred Draked86ed291999-12-15 15:34:33 +000011273
11274
Larry Hastings2f936352014-08-05 14:04:04 +100011275/*[clinic input]
11276os.abort
11277
11278Abort the interpreter immediately.
11279
11280This function 'dumps core' or otherwise fails in the hardest way possible
11281on the hosting operating system. This function never returns.
11282[clinic start generated code]*/
11283
Larry Hastings2f936352014-08-05 14:04:04 +100011284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011285os_abort_impl(PyObject *module)
11286/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011287{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011288 abort();
11289 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011290#ifndef __clang__
11291 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11292 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11293 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011294 Py_FatalError("abort() called from Python code didn't abort!");
11295 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011296#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011297}
Fred Drakebec628d1999-12-15 18:31:10 +000011298
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011299#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011300/* Grab ShellExecute dynamically from shell32 */
11301static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011302static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11303 LPCWSTR, INT);
11304static int
11305check_ShellExecute()
11306{
11307 HINSTANCE hShell32;
11308
11309 /* only recheck */
11310 if (-1 == has_ShellExecute) {
11311 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011312 /* Security note: this call is not vulnerable to "DLL hijacking".
11313 SHELL32 is part of "KnownDLLs" and so Windows always load
11314 the system SHELL32.DLL, even if there is another SHELL32.DLL
11315 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011316 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011317 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011318 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11319 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011320 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011321 } else {
11322 has_ShellExecute = 0;
11323 }
Tony Roberts4860f012019-02-02 18:16:42 +010011324 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011325 }
11326 return has_ShellExecute;
11327}
11328
11329
Steve Dowercc16be82016-09-08 10:35:16 -070011330/*[clinic input]
11331os.startfile
11332 filepath: path_t
11333 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011334
Steve Dowercc16be82016-09-08 10:35:16 -070011335startfile(filepath [, operation])
11336
11337Start a file with its associated application.
11338
11339When "operation" is not specified or "open", this acts like
11340double-clicking the file in Explorer, or giving the file name as an
11341argument to the DOS "start" command: the file is opened with whatever
11342application (if any) its extension is associated.
11343When another "operation" is given, it specifies what should be done with
11344the file. A typical operation is "print".
11345
11346startfile returns as soon as the associated application is launched.
11347There is no option to wait for the application to close, and no way
11348to retrieve the application's exit status.
11349
11350The filepath is relative to the current directory. If you want to use
11351an absolute path, make sure the first character is not a slash ("/");
11352the underlying Win32 ShellExecute function doesn't work if it is.
11353[clinic start generated code]*/
11354
11355static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011356os_startfile_impl(PyObject *module, path_t *filepath,
11357 const Py_UNICODE *operation)
11358/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011359{
11360 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011361
11362 if(!check_ShellExecute()) {
11363 /* If the OS doesn't have ShellExecute, return a
11364 NotImplementedError. */
11365 return PyErr_Format(PyExc_NotImplementedError,
11366 "startfile not available on this platform");
11367 }
11368
Victor Stinner8c62be82010-05-06 00:08:46 +000011369 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011370 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011371 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 Py_END_ALLOW_THREADS
11373
Victor Stinner8c62be82010-05-06 00:08:46 +000011374 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011375 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011376 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011377 }
Steve Dowercc16be82016-09-08 10:35:16 -070011378 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011379}
Larry Hastings2f936352014-08-05 14:04:04 +100011380#endif /* MS_WINDOWS */
11381
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011382
Martin v. Löwis438b5342002-12-27 10:16:42 +000011383#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011384/*[clinic input]
11385os.getloadavg
11386
11387Return average recent system load information.
11388
11389Return the number of processes in the system run queue averaged over
11390the last 1, 5, and 15 minutes as a tuple of three floats.
11391Raises OSError if the load average was unobtainable.
11392[clinic start generated code]*/
11393
Larry Hastings2f936352014-08-05 14:04:04 +100011394static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011395os_getloadavg_impl(PyObject *module)
11396/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011397{
11398 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011399 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011400 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11401 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011402 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011403 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011404}
Larry Hastings2f936352014-08-05 14:04:04 +100011405#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011406
Larry Hastings2f936352014-08-05 14:04:04 +100011407
11408/*[clinic input]
11409os.device_encoding
11410 fd: int
11411
11412Return a string describing the encoding of a terminal's file descriptor.
11413
11414The file descriptor must be attached to a terminal.
11415If the device is not a terminal, return None.
11416[clinic start generated code]*/
11417
Larry Hastings2f936352014-08-05 14:04:04 +100011418static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011419os_device_encoding_impl(PyObject *module, int fd)
11420/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011421{
Brett Cannonefb00c02012-02-29 18:31:31 -050011422 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011423}
11424
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011425
Larry Hastings2f936352014-08-05 14:04:04 +100011426#ifdef HAVE_SETRESUID
11427/*[clinic input]
11428os.setresuid
11429
11430 ruid: uid_t
11431 euid: uid_t
11432 suid: uid_t
11433 /
11434
11435Set the current process's real, effective, and saved user ids.
11436[clinic start generated code]*/
11437
Larry Hastings2f936352014-08-05 14:04:04 +100011438static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011439os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11440/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011441{
Victor Stinner8c62be82010-05-06 00:08:46 +000011442 if (setresuid(ruid, euid, suid) < 0)
11443 return posix_error();
11444 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011445}
Larry Hastings2f936352014-08-05 14:04:04 +100011446#endif /* HAVE_SETRESUID */
11447
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011448
11449#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011450/*[clinic input]
11451os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011452
Larry Hastings2f936352014-08-05 14:04:04 +100011453 rgid: gid_t
11454 egid: gid_t
11455 sgid: gid_t
11456 /
11457
11458Set the current process's real, effective, and saved group ids.
11459[clinic start generated code]*/
11460
Larry Hastings2f936352014-08-05 14:04:04 +100011461static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011462os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11463/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011464{
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 if (setresgid(rgid, egid, sgid) < 0)
11466 return posix_error();
11467 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011468}
Larry Hastings2f936352014-08-05 14:04:04 +100011469#endif /* HAVE_SETRESGID */
11470
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011471
11472#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011473/*[clinic input]
11474os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011475
Larry Hastings2f936352014-08-05 14:04:04 +100011476Return a tuple of the current process's real, effective, and saved user ids.
11477[clinic start generated code]*/
11478
Larry Hastings2f936352014-08-05 14:04:04 +100011479static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011480os_getresuid_impl(PyObject *module)
11481/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011482{
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011484 if (getresuid(&ruid, &euid, &suid) < 0)
11485 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011486 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11487 _PyLong_FromUid(euid),
11488 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011489}
Larry Hastings2f936352014-08-05 14:04:04 +100011490#endif /* HAVE_GETRESUID */
11491
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011492
11493#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011494/*[clinic input]
11495os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011496
Larry Hastings2f936352014-08-05 14:04:04 +100011497Return a tuple of the current process's real, effective, and saved group ids.
11498[clinic start generated code]*/
11499
Larry Hastings2f936352014-08-05 14:04:04 +100011500static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011501os_getresgid_impl(PyObject *module)
11502/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011503{
11504 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011505 if (getresgid(&rgid, &egid, &sgid) < 0)
11506 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011507 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11508 _PyLong_FromGid(egid),
11509 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011510}
Larry Hastings2f936352014-08-05 14:04:04 +100011511#endif /* HAVE_GETRESGID */
11512
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011513
Benjamin Peterson9428d532011-09-14 11:45:52 -040011514#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011515/*[clinic input]
11516os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011517
Larry Hastings2f936352014-08-05 14:04:04 +100011518 path: path_t(allow_fd=True)
11519 attribute: path_t
11520 *
11521 follow_symlinks: bool = True
11522
11523Return the value of extended attribute attribute on path.
11524
BNMetricsb9427072018-11-02 15:20:19 +000011525path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011526If follow_symlinks is False, and the last element of the path is a symbolic
11527 link, getxattr will examine the symbolic link itself instead of the file
11528 the link points to.
11529
11530[clinic start generated code]*/
11531
Larry Hastings2f936352014-08-05 14:04:04 +100011532static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011533os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011534 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011535/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011536{
11537 Py_ssize_t i;
11538 PyObject *buffer = NULL;
11539
11540 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11541 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011542
Larry Hastings9cf065c2012-06-22 16:30:09 -070011543 for (i = 0; ; i++) {
11544 void *ptr;
11545 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011546 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011547 Py_ssize_t buffer_size = buffer_sizes[i];
11548 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011549 path_error(path);
11550 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011551 }
11552 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11553 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011554 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011555 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011556
Larry Hastings9cf065c2012-06-22 16:30:09 -070011557 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011558 if (path->fd >= 0)
11559 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011560 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011561 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011562 else
Larry Hastings2f936352014-08-05 14:04:04 +100011563 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011564 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011565
Larry Hastings9cf065c2012-06-22 16:30:09 -070011566 if (result < 0) {
11567 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011568 if (errno == ERANGE)
11569 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011570 path_error(path);
11571 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011572 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011573
Larry Hastings9cf065c2012-06-22 16:30:09 -070011574 if (result != buffer_size) {
11575 /* Can only shrink. */
11576 _PyBytes_Resize(&buffer, result);
11577 }
11578 break;
11579 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011580
Larry Hastings9cf065c2012-06-22 16:30:09 -070011581 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011582}
11583
Larry Hastings2f936352014-08-05 14:04:04 +100011584
11585/*[clinic input]
11586os.setxattr
11587
11588 path: path_t(allow_fd=True)
11589 attribute: path_t
11590 value: Py_buffer
11591 flags: int = 0
11592 *
11593 follow_symlinks: bool = True
11594
11595Set extended attribute attribute on path to value.
11596
BNMetricsb9427072018-11-02 15:20:19 +000011597path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011598If follow_symlinks is False, and the last element of the path is a symbolic
11599 link, setxattr will modify the symbolic link itself instead of the file
11600 the link points to.
11601
11602[clinic start generated code]*/
11603
Benjamin Peterson799bd802011-08-31 22:15:17 -040011604static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011605os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011606 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011607/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011608{
Larry Hastings2f936352014-08-05 14:04:04 +100011609 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011610
Larry Hastings2f936352014-08-05 14:04:04 +100011611 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011612 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011613
Benjamin Peterson799bd802011-08-31 22:15:17 -040011614 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011615 if (path->fd > -1)
11616 result = fsetxattr(path->fd, attribute->narrow,
11617 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011618 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011619 result = setxattr(path->narrow, attribute->narrow,
11620 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011621 else
Larry Hastings2f936352014-08-05 14:04:04 +100011622 result = lsetxattr(path->narrow, attribute->narrow,
11623 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011624 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011625
Larry Hastings9cf065c2012-06-22 16:30:09 -070011626 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011627 path_error(path);
11628 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011629 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011630
Larry Hastings2f936352014-08-05 14:04:04 +100011631 Py_RETURN_NONE;
11632}
11633
11634
11635/*[clinic input]
11636os.removexattr
11637
11638 path: path_t(allow_fd=True)
11639 attribute: path_t
11640 *
11641 follow_symlinks: bool = True
11642
11643Remove extended attribute attribute on path.
11644
BNMetricsb9427072018-11-02 15:20:19 +000011645path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011646If follow_symlinks is False, and the last element of the path is a symbolic
11647 link, removexattr will modify the symbolic link itself instead of the file
11648 the link points to.
11649
11650[clinic start generated code]*/
11651
Larry Hastings2f936352014-08-05 14:04:04 +100011652static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011653os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011654 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011655/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011656{
11657 ssize_t result;
11658
11659 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11660 return NULL;
11661
11662 Py_BEGIN_ALLOW_THREADS;
11663 if (path->fd > -1)
11664 result = fremovexattr(path->fd, attribute->narrow);
11665 else if (follow_symlinks)
11666 result = removexattr(path->narrow, attribute->narrow);
11667 else
11668 result = lremovexattr(path->narrow, attribute->narrow);
11669 Py_END_ALLOW_THREADS;
11670
11671 if (result) {
11672 return path_error(path);
11673 }
11674
11675 Py_RETURN_NONE;
11676}
11677
11678
11679/*[clinic input]
11680os.listxattr
11681
11682 path: path_t(allow_fd=True, nullable=True) = None
11683 *
11684 follow_symlinks: bool = True
11685
11686Return a list of extended attributes on path.
11687
BNMetricsb9427072018-11-02 15:20:19 +000011688path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011689if path is None, listxattr will examine the current directory.
11690If follow_symlinks is False, and the last element of the path is a symbolic
11691 link, listxattr will examine the symbolic link itself instead of the file
11692 the link points to.
11693[clinic start generated code]*/
11694
Larry Hastings2f936352014-08-05 14:04:04 +100011695static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011696os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011697/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011698{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011699 Py_ssize_t i;
11700 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011701 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011702 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011703
Larry Hastings2f936352014-08-05 14:04:04 +100011704 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011705 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011706
Larry Hastings2f936352014-08-05 14:04:04 +100011707 name = path->narrow ? path->narrow : ".";
11708
Larry Hastings9cf065c2012-06-22 16:30:09 -070011709 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011710 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011711 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011712 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011713 Py_ssize_t buffer_size = buffer_sizes[i];
11714 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011715 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011716 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011717 break;
11718 }
11719 buffer = PyMem_MALLOC(buffer_size);
11720 if (!buffer) {
11721 PyErr_NoMemory();
11722 break;
11723 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011724
Larry Hastings9cf065c2012-06-22 16:30:09 -070011725 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011726 if (path->fd > -1)
11727 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011728 else if (follow_symlinks)
11729 length = listxattr(name, buffer, buffer_size);
11730 else
11731 length = llistxattr(name, buffer, buffer_size);
11732 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011733
Larry Hastings9cf065c2012-06-22 16:30:09 -070011734 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011735 if (errno == ERANGE) {
11736 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011737 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011738 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011739 }
Larry Hastings2f936352014-08-05 14:04:04 +100011740 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011741 break;
11742 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011743
Larry Hastings9cf065c2012-06-22 16:30:09 -070011744 result = PyList_New(0);
11745 if (!result) {
11746 goto exit;
11747 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011748
Larry Hastings9cf065c2012-06-22 16:30:09 -070011749 end = buffer + length;
11750 for (trace = start = buffer; trace != end; trace++) {
11751 if (!*trace) {
11752 int error;
11753 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11754 trace - start);
11755 if (!attribute) {
11756 Py_DECREF(result);
11757 result = NULL;
11758 goto exit;
11759 }
11760 error = PyList_Append(result, attribute);
11761 Py_DECREF(attribute);
11762 if (error) {
11763 Py_DECREF(result);
11764 result = NULL;
11765 goto exit;
11766 }
11767 start = trace + 1;
11768 }
11769 }
11770 break;
11771 }
11772exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011773 if (buffer)
11774 PyMem_FREE(buffer);
11775 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011776}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011777#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011778
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011779
Larry Hastings2f936352014-08-05 14:04:04 +100011780/*[clinic input]
11781os.urandom
11782
11783 size: Py_ssize_t
11784 /
11785
11786Return a bytes object containing random bytes suitable for cryptographic use.
11787[clinic start generated code]*/
11788
Larry Hastings2f936352014-08-05 14:04:04 +100011789static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011790os_urandom_impl(PyObject *module, Py_ssize_t size)
11791/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011792{
11793 PyObject *bytes;
11794 int result;
11795
Georg Brandl2fb477c2012-02-21 00:33:36 +010011796 if (size < 0)
11797 return PyErr_Format(PyExc_ValueError,
11798 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011799 bytes = PyBytes_FromStringAndSize(NULL, size);
11800 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011801 return NULL;
11802
Victor Stinnere66987e2016-09-06 16:33:52 -070011803 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011804 if (result == -1) {
11805 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011806 return NULL;
11807 }
Larry Hastings2f936352014-08-05 14:04:04 +100011808 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011809}
11810
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011811/* Terminal size querying */
11812
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011813static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011814
11815PyDoc_STRVAR(TerminalSize_docstring,
11816 "A tuple of (columns, lines) for holding terminal window size");
11817
11818static PyStructSequence_Field TerminalSize_fields[] = {
11819 {"columns", "width of the terminal window in characters"},
11820 {"lines", "height of the terminal window in characters"},
11821 {NULL, NULL}
11822};
11823
11824static PyStructSequence_Desc TerminalSize_desc = {
11825 "os.terminal_size",
11826 TerminalSize_docstring,
11827 TerminalSize_fields,
11828 2,
11829};
11830
11831#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011832/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011833PyDoc_STRVAR(termsize__doc__,
11834 "Return the size of the terminal window as (columns, lines).\n" \
11835 "\n" \
11836 "The optional argument fd (default standard output) specifies\n" \
11837 "which file descriptor should be queried.\n" \
11838 "\n" \
11839 "If the file descriptor is not connected to a terminal, an OSError\n" \
11840 "is thrown.\n" \
11841 "\n" \
11842 "This function will only be defined if an implementation is\n" \
11843 "available for this system.\n" \
11844 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080011845 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011846 "normally be used, os.get_terminal_size is the low-level implementation.");
11847
11848static PyObject*
11849get_terminal_size(PyObject *self, PyObject *args)
11850{
11851 int columns, lines;
11852 PyObject *termsize;
11853
11854 int fd = fileno(stdout);
11855 /* Under some conditions stdout may not be connected and
11856 * fileno(stdout) may point to an invalid file descriptor. For example
11857 * GUI apps don't have valid standard streams by default.
11858 *
11859 * If this happens, and the optional fd argument is not present,
11860 * the ioctl below will fail returning EBADF. This is what we want.
11861 */
11862
11863 if (!PyArg_ParseTuple(args, "|i", &fd))
11864 return NULL;
11865
11866#ifdef TERMSIZE_USE_IOCTL
11867 {
11868 struct winsize w;
11869 if (ioctl(fd, TIOCGWINSZ, &w))
11870 return PyErr_SetFromErrno(PyExc_OSError);
11871 columns = w.ws_col;
11872 lines = w.ws_row;
11873 }
11874#endif /* TERMSIZE_USE_IOCTL */
11875
11876#ifdef TERMSIZE_USE_CONIO
11877 {
11878 DWORD nhandle;
11879 HANDLE handle;
11880 CONSOLE_SCREEN_BUFFER_INFO csbi;
11881 switch (fd) {
11882 case 0: nhandle = STD_INPUT_HANDLE;
11883 break;
11884 case 1: nhandle = STD_OUTPUT_HANDLE;
11885 break;
11886 case 2: nhandle = STD_ERROR_HANDLE;
11887 break;
11888 default:
11889 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11890 }
11891 handle = GetStdHandle(nhandle);
11892 if (handle == NULL)
11893 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11894 if (handle == INVALID_HANDLE_VALUE)
11895 return PyErr_SetFromWindowsErr(0);
11896
11897 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11898 return PyErr_SetFromWindowsErr(0);
11899
11900 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11901 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11902 }
11903#endif /* TERMSIZE_USE_CONIO */
11904
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011905 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011906 if (termsize == NULL)
11907 return NULL;
11908 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11909 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11910 if (PyErr_Occurred()) {
11911 Py_DECREF(termsize);
11912 return NULL;
11913 }
11914 return termsize;
11915}
11916#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11917
Larry Hastings2f936352014-08-05 14:04:04 +100011918
11919/*[clinic input]
11920os.cpu_count
11921
Charles-François Natali80d62e62015-08-13 20:37:08 +010011922Return the number of CPUs in the system; return None if indeterminable.
11923
11924This number is not equivalent to the number of CPUs the current process can
11925use. The number of usable CPUs can be obtained with
11926``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011927[clinic start generated code]*/
11928
Larry Hastings2f936352014-08-05 14:04:04 +100011929static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011930os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011931/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011932{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011933 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011934#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011935 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11936 Need to fallback to Vista behavior if this call isn't present */
11937 HINSTANCE hKernel32;
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011938 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
Tony Roberts4860f012019-02-02 18:16:42 +010011939 Py_BEGIN_ALLOW_THREADS
11940 hKernel32 = GetModuleHandleW(L"KERNEL32");
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011941 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11942 "GetMaximumProcessorCount");
Tony Roberts4860f012019-02-02 18:16:42 +010011943 Py_END_ALLOW_THREADS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011944 if (_GetMaximumProcessorCount != NULL) {
11945 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11946 }
11947 else {
11948 SYSTEM_INFO sysinfo;
11949 GetSystemInfo(&sysinfo);
11950 ncpu = sysinfo.dwNumberOfProcessors;
11951 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011952#elif defined(__hpux)
11953 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11954#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11955 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011956#elif defined(__DragonFly__) || \
11957 defined(__OpenBSD__) || \
11958 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011959 defined(__NetBSD__) || \
11960 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011961 int mib[2];
11962 size_t len = sizeof(ncpu);
11963 mib[0] = CTL_HW;
11964 mib[1] = HW_NCPU;
11965 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11966 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011967#endif
11968 if (ncpu >= 1)
11969 return PyLong_FromLong(ncpu);
11970 else
11971 Py_RETURN_NONE;
11972}
11973
Victor Stinnerdaf45552013-08-28 00:53:59 +020011974
Larry Hastings2f936352014-08-05 14:04:04 +100011975/*[clinic input]
11976os.get_inheritable -> bool
11977
11978 fd: int
11979 /
11980
11981Get the close-on-exe flag of the specified file descriptor.
11982[clinic start generated code]*/
11983
Larry Hastings2f936352014-08-05 14:04:04 +100011984static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011985os_get_inheritable_impl(PyObject *module, int fd)
11986/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011987{
Steve Dower8fc89802015-04-12 00:26:27 -040011988 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011989 _Py_BEGIN_SUPPRESS_IPH
11990 return_value = _Py_get_inheritable(fd);
11991 _Py_END_SUPPRESS_IPH
11992 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011993}
11994
11995
11996/*[clinic input]
11997os.set_inheritable
11998 fd: int
11999 inheritable: int
12000 /
12001
12002Set the inheritable flag of the specified file descriptor.
12003[clinic start generated code]*/
12004
Larry Hastings2f936352014-08-05 14:04:04 +100012005static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012006os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12007/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012008{
Steve Dower8fc89802015-04-12 00:26:27 -040012009 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012010
Steve Dower8fc89802015-04-12 00:26:27 -040012011 _Py_BEGIN_SUPPRESS_IPH
12012 result = _Py_set_inheritable(fd, inheritable, NULL);
12013 _Py_END_SUPPRESS_IPH
12014 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012015 return NULL;
12016 Py_RETURN_NONE;
12017}
12018
12019
12020#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012021/*[clinic input]
12022os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012023 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012024 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012025
Larry Hastings2f936352014-08-05 14:04:04 +100012026Get the close-on-exe flag of the specified file descriptor.
12027[clinic start generated code]*/
12028
Larry Hastings2f936352014-08-05 14:04:04 +100012029static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012030os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012031/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012032{
12033 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012034
12035 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12036 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012037 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012038 }
12039
Larry Hastings2f936352014-08-05 14:04:04 +100012040 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012041}
12042
Victor Stinnerdaf45552013-08-28 00:53:59 +020012043
Larry Hastings2f936352014-08-05 14:04:04 +100012044/*[clinic input]
12045os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012046 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012047 inheritable: bool
12048 /
12049
12050Set the inheritable flag of the specified handle.
12051[clinic start generated code]*/
12052
Larry Hastings2f936352014-08-05 14:04:04 +100012053static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012054os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012055 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012056/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012057{
12058 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012059 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12060 PyErr_SetFromWindowsErr(0);
12061 return NULL;
12062 }
12063 Py_RETURN_NONE;
12064}
Larry Hastings2f936352014-08-05 14:04:04 +100012065#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012066
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012067#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012068/*[clinic input]
12069os.get_blocking -> bool
12070 fd: int
12071 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012072
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012073Get the blocking mode of the file descriptor.
12074
12075Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12076[clinic start generated code]*/
12077
12078static int
12079os_get_blocking_impl(PyObject *module, int fd)
12080/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012081{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012082 int blocking;
12083
Steve Dower8fc89802015-04-12 00:26:27 -040012084 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012085 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012086 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012087 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012088}
12089
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012090/*[clinic input]
12091os.set_blocking
12092 fd: int
12093 blocking: bool(accept={int})
12094 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012095
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012096Set the blocking mode of the specified file descriptor.
12097
12098Set the O_NONBLOCK flag if blocking is False,
12099clear the O_NONBLOCK flag otherwise.
12100[clinic start generated code]*/
12101
12102static PyObject *
12103os_set_blocking_impl(PyObject *module, int fd, int blocking)
12104/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012105{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012106 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012107
Steve Dower8fc89802015-04-12 00:26:27 -040012108 _Py_BEGIN_SUPPRESS_IPH
12109 result = _Py_set_blocking(fd, blocking);
12110 _Py_END_SUPPRESS_IPH
12111 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012112 return NULL;
12113 Py_RETURN_NONE;
12114}
12115#endif /* !MS_WINDOWS */
12116
12117
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012118/*[clinic input]
12119class os.DirEntry "DirEntry *" "&DirEntryType"
12120[clinic start generated code]*/
12121/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012122
12123typedef struct {
12124 PyObject_HEAD
12125 PyObject *name;
12126 PyObject *path;
12127 PyObject *stat;
12128 PyObject *lstat;
12129#ifdef MS_WINDOWS
12130 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012131 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012132 int got_file_index;
12133#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012134#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012135 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012136#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012137 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012138 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012139#endif
12140} DirEntry;
12141
12142static void
12143DirEntry_dealloc(DirEntry *entry)
12144{
12145 Py_XDECREF(entry->name);
12146 Py_XDECREF(entry->path);
12147 Py_XDECREF(entry->stat);
12148 Py_XDECREF(entry->lstat);
12149 Py_TYPE(entry)->tp_free((PyObject *)entry);
12150}
12151
12152/* Forward reference */
12153static int
12154DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12155
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012156/*[clinic input]
12157os.DirEntry.is_symlink -> bool
12158
12159Return True if the entry is a symbolic link; cached per entry.
12160[clinic start generated code]*/
12161
Victor Stinner6036e442015-03-08 01:58:04 +010012162static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012163os_DirEntry_is_symlink_impl(DirEntry *self)
12164/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012165{
12166#ifdef MS_WINDOWS
12167 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012168#elif defined(HAVE_DIRENT_D_TYPE)
12169 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012170 if (self->d_type != DT_UNKNOWN)
12171 return self->d_type == DT_LNK;
12172 else
12173 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012174#else
12175 /* POSIX without d_type */
12176 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012177#endif
12178}
12179
12180static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012181DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12182{
12183 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012184 STRUCT_STAT st;
12185 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012186
12187#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012188 if (!PyUnicode_FSDecoder(self->path, &ub))
12189 return NULL;
12190 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012191#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012192 if (!PyUnicode_FSConverter(self->path, &ub))
12193 return NULL;
12194 const char *path = PyBytes_AS_STRING(ub);
12195 if (self->dir_fd != DEFAULT_DIR_FD) {
12196#ifdef HAVE_FSTATAT
12197 result = fstatat(self->dir_fd, path, &st,
12198 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12199#else
12200 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12201 return NULL;
12202#endif /* HAVE_FSTATAT */
12203 }
12204 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012205#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012206 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012207 if (follow_symlinks)
12208 result = STAT(path, &st);
12209 else
12210 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012211 }
12212 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012213
12214 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012215 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012216
12217 return _pystat_fromstructstat(&st);
12218}
12219
12220static PyObject *
12221DirEntry_get_lstat(DirEntry *self)
12222{
12223 if (!self->lstat) {
12224#ifdef MS_WINDOWS
12225 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12226#else /* POSIX */
12227 self->lstat = DirEntry_fetch_stat(self, 0);
12228#endif
12229 }
12230 Py_XINCREF(self->lstat);
12231 return self->lstat;
12232}
12233
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012234/*[clinic input]
12235os.DirEntry.stat
12236 *
12237 follow_symlinks: bool = True
12238
12239Return stat_result object for the entry; cached per entry.
12240[clinic start generated code]*/
12241
Victor Stinner6036e442015-03-08 01:58:04 +010012242static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012243os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12244/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012245{
12246 if (!follow_symlinks)
12247 return DirEntry_get_lstat(self);
12248
12249 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012250 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012251 if (result == -1)
12252 return NULL;
12253 else if (result)
12254 self->stat = DirEntry_fetch_stat(self, 1);
12255 else
12256 self->stat = DirEntry_get_lstat(self);
12257 }
12258
12259 Py_XINCREF(self->stat);
12260 return self->stat;
12261}
12262
Victor Stinner6036e442015-03-08 01:58:04 +010012263/* Set exception and return -1 on error, 0 for False, 1 for True */
12264static int
12265DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12266{
12267 PyObject *stat = NULL;
12268 PyObject *st_mode = NULL;
12269 long mode;
12270 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012271#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012272 int is_symlink;
12273 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012274#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012275#ifdef MS_WINDOWS
12276 unsigned long dir_bits;
12277#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012278 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012279
12280#ifdef MS_WINDOWS
12281 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12282 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012283#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012284 is_symlink = self->d_type == DT_LNK;
12285 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12286#endif
12287
Victor Stinner35a97c02015-03-08 02:59:09 +010012288#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012289 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012290#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012291 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012292 if (!stat) {
12293 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12294 /* If file doesn't exist (anymore), then return False
12295 (i.e., say it's not a file/directory) */
12296 PyErr_Clear();
12297 return 0;
12298 }
12299 goto error;
12300 }
12301 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12302 if (!st_mode)
12303 goto error;
12304
12305 mode = PyLong_AsLong(st_mode);
12306 if (mode == -1 && PyErr_Occurred())
12307 goto error;
12308 Py_CLEAR(st_mode);
12309 Py_CLEAR(stat);
12310 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012311#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012312 }
12313 else if (is_symlink) {
12314 assert(mode_bits != S_IFLNK);
12315 result = 0;
12316 }
12317 else {
12318 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12319#ifdef MS_WINDOWS
12320 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12321 if (mode_bits == S_IFDIR)
12322 result = dir_bits != 0;
12323 else
12324 result = dir_bits == 0;
12325#else /* POSIX */
12326 if (mode_bits == S_IFDIR)
12327 result = self->d_type == DT_DIR;
12328 else
12329 result = self->d_type == DT_REG;
12330#endif
12331 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012332#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012333
12334 return result;
12335
12336error:
12337 Py_XDECREF(st_mode);
12338 Py_XDECREF(stat);
12339 return -1;
12340}
12341
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012342/*[clinic input]
12343os.DirEntry.is_dir -> bool
12344 *
12345 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012346
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012347Return True if the entry is a directory; cached per entry.
12348[clinic start generated code]*/
12349
12350static int
12351os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12352/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12353{
12354 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012355}
12356
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012357/*[clinic input]
12358os.DirEntry.is_file -> bool
12359 *
12360 follow_symlinks: bool = True
12361
12362Return True if the entry is a file; cached per entry.
12363[clinic start generated code]*/
12364
12365static int
12366os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12367/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012368{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012369 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012370}
12371
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012372/*[clinic input]
12373os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012374
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012375Return inode of the entry; cached per entry.
12376[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012377
12378static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012379os_DirEntry_inode_impl(DirEntry *self)
12380/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012381{
12382#ifdef MS_WINDOWS
12383 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012384 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012385 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012386 STRUCT_STAT stat;
12387 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012388
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012389 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012390 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012391 path = PyUnicode_AsUnicode(unicode);
12392 result = LSTAT(path, &stat);
12393 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012394
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012395 if (result != 0)
12396 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012397
12398 self->win32_file_index = stat.st_ino;
12399 self->got_file_index = 1;
12400 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012401 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12402 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012403#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012404 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12405 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012406#endif
12407}
12408
12409static PyObject *
12410DirEntry_repr(DirEntry *self)
12411{
12412 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12413}
12414
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012415/*[clinic input]
12416os.DirEntry.__fspath__
12417
12418Returns the path for the entry.
12419[clinic start generated code]*/
12420
Brett Cannon96881cd2016-06-10 14:37:21 -070012421static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012422os_DirEntry___fspath___impl(DirEntry *self)
12423/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012424{
12425 Py_INCREF(self->path);
12426 return self->path;
12427}
12428
Victor Stinner6036e442015-03-08 01:58:04 +010012429static PyMemberDef DirEntry_members[] = {
12430 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12431 "the entry's base filename, relative to scandir() \"path\" argument"},
12432 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12433 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12434 {NULL}
12435};
12436
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012437#include "clinic/posixmodule.c.h"
12438
Victor Stinner6036e442015-03-08 01:58:04 +010012439static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012440 OS_DIRENTRY_IS_DIR_METHODDEF
12441 OS_DIRENTRY_IS_FILE_METHODDEF
12442 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12443 OS_DIRENTRY_STAT_METHODDEF
12444 OS_DIRENTRY_INODE_METHODDEF
12445 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012446 {NULL}
12447};
12448
Benjamin Peterson5646de42015-04-12 17:56:34 -040012449static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012450 PyVarObject_HEAD_INIT(NULL, 0)
12451 MODNAME ".DirEntry", /* tp_name */
12452 sizeof(DirEntry), /* tp_basicsize */
12453 0, /* tp_itemsize */
12454 /* methods */
12455 (destructor)DirEntry_dealloc, /* tp_dealloc */
12456 0, /* tp_print */
12457 0, /* tp_getattr */
12458 0, /* tp_setattr */
12459 0, /* tp_compare */
12460 (reprfunc)DirEntry_repr, /* tp_repr */
12461 0, /* tp_as_number */
12462 0, /* tp_as_sequence */
12463 0, /* tp_as_mapping */
12464 0, /* tp_hash */
12465 0, /* tp_call */
12466 0, /* tp_str */
12467 0, /* tp_getattro */
12468 0, /* tp_setattro */
12469 0, /* tp_as_buffer */
12470 Py_TPFLAGS_DEFAULT, /* tp_flags */
12471 0, /* tp_doc */
12472 0, /* tp_traverse */
12473 0, /* tp_clear */
12474 0, /* tp_richcompare */
12475 0, /* tp_weaklistoffset */
12476 0, /* tp_iter */
12477 0, /* tp_iternext */
12478 DirEntry_methods, /* tp_methods */
12479 DirEntry_members, /* tp_members */
12480};
12481
12482#ifdef MS_WINDOWS
12483
12484static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012485join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012486{
12487 Py_ssize_t path_len;
12488 Py_ssize_t size;
12489 wchar_t *result;
12490 wchar_t ch;
12491
12492 if (!path_wide) { /* Default arg: "." */
12493 path_wide = L".";
12494 path_len = 1;
12495 }
12496 else {
12497 path_len = wcslen(path_wide);
12498 }
12499
12500 /* The +1's are for the path separator and the NUL */
12501 size = path_len + 1 + wcslen(filename) + 1;
12502 result = PyMem_New(wchar_t, size);
12503 if (!result) {
12504 PyErr_NoMemory();
12505 return NULL;
12506 }
12507 wcscpy(result, path_wide);
12508 if (path_len > 0) {
12509 ch = result[path_len - 1];
12510 if (ch != SEP && ch != ALTSEP && ch != L':')
12511 result[path_len++] = SEP;
12512 wcscpy(result + path_len, filename);
12513 }
12514 return result;
12515}
12516
12517static PyObject *
12518DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12519{
12520 DirEntry *entry;
12521 BY_HANDLE_FILE_INFORMATION file_info;
12522 ULONG reparse_tag;
12523 wchar_t *joined_path;
12524
12525 entry = PyObject_New(DirEntry, &DirEntryType);
12526 if (!entry)
12527 return NULL;
12528 entry->name = NULL;
12529 entry->path = NULL;
12530 entry->stat = NULL;
12531 entry->lstat = NULL;
12532 entry->got_file_index = 0;
12533
12534 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12535 if (!entry->name)
12536 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012537 if (path->narrow) {
12538 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12539 if (!entry->name)
12540 goto error;
12541 }
Victor Stinner6036e442015-03-08 01:58:04 +010012542
12543 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12544 if (!joined_path)
12545 goto error;
12546
12547 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12548 PyMem_Free(joined_path);
12549 if (!entry->path)
12550 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012551 if (path->narrow) {
12552 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12553 if (!entry->path)
12554 goto error;
12555 }
Victor Stinner6036e442015-03-08 01:58:04 +010012556
Steve Dowercc16be82016-09-08 10:35:16 -070012557 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012558 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12559
12560 return (PyObject *)entry;
12561
12562error:
12563 Py_DECREF(entry);
12564 return NULL;
12565}
12566
12567#else /* POSIX */
12568
12569static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012570join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012571{
12572 Py_ssize_t path_len;
12573 Py_ssize_t size;
12574 char *result;
12575
12576 if (!path_narrow) { /* Default arg: "." */
12577 path_narrow = ".";
12578 path_len = 1;
12579 }
12580 else {
12581 path_len = strlen(path_narrow);
12582 }
12583
12584 if (filename_len == -1)
12585 filename_len = strlen(filename);
12586
12587 /* The +1's are for the path separator and the NUL */
12588 size = path_len + 1 + filename_len + 1;
12589 result = PyMem_New(char, size);
12590 if (!result) {
12591 PyErr_NoMemory();
12592 return NULL;
12593 }
12594 strcpy(result, path_narrow);
12595 if (path_len > 0 && result[path_len - 1] != '/')
12596 result[path_len++] = '/';
12597 strcpy(result + path_len, filename);
12598 return result;
12599}
12600
12601static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012602DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012603 ino_t d_ino
12604#ifdef HAVE_DIRENT_D_TYPE
12605 , unsigned char d_type
12606#endif
12607 )
Victor Stinner6036e442015-03-08 01:58:04 +010012608{
12609 DirEntry *entry;
12610 char *joined_path;
12611
12612 entry = PyObject_New(DirEntry, &DirEntryType);
12613 if (!entry)
12614 return NULL;
12615 entry->name = NULL;
12616 entry->path = NULL;
12617 entry->stat = NULL;
12618 entry->lstat = NULL;
12619
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012620 if (path->fd != -1) {
12621 entry->dir_fd = path->fd;
12622 joined_path = NULL;
12623 }
12624 else {
12625 entry->dir_fd = DEFAULT_DIR_FD;
12626 joined_path = join_path_filename(path->narrow, name, name_len);
12627 if (!joined_path)
12628 goto error;
12629 }
Victor Stinner6036e442015-03-08 01:58:04 +010012630
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012631 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012632 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012633 if (joined_path)
12634 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012635 }
12636 else {
12637 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012638 if (joined_path)
12639 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012640 }
12641 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012642 if (!entry->name)
12643 goto error;
12644
12645 if (path->fd != -1) {
12646 entry->path = entry->name;
12647 Py_INCREF(entry->path);
12648 }
12649 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012650 goto error;
12651
Victor Stinner35a97c02015-03-08 02:59:09 +010012652#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012653 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012654#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012655 entry->d_ino = d_ino;
12656
12657 return (PyObject *)entry;
12658
12659error:
12660 Py_XDECREF(entry);
12661 return NULL;
12662}
12663
12664#endif
12665
12666
12667typedef struct {
12668 PyObject_HEAD
12669 path_t path;
12670#ifdef MS_WINDOWS
12671 HANDLE handle;
12672 WIN32_FIND_DATAW file_data;
12673 int first_time;
12674#else /* POSIX */
12675 DIR *dirp;
12676#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012677#ifdef HAVE_FDOPENDIR
12678 int fd;
12679#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012680} ScandirIterator;
12681
12682#ifdef MS_WINDOWS
12683
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012684static int
12685ScandirIterator_is_closed(ScandirIterator *iterator)
12686{
12687 return iterator->handle == INVALID_HANDLE_VALUE;
12688}
12689
Victor Stinner6036e442015-03-08 01:58:04 +010012690static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012691ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012692{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012693 HANDLE handle = iterator->handle;
12694
12695 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012696 return;
12697
Victor Stinner6036e442015-03-08 01:58:04 +010012698 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012699 Py_BEGIN_ALLOW_THREADS
12700 FindClose(handle);
12701 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012702}
12703
12704static PyObject *
12705ScandirIterator_iternext(ScandirIterator *iterator)
12706{
12707 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12708 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012709 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012710
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012711 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012712 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012713 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012714
12715 while (1) {
12716 if (!iterator->first_time) {
12717 Py_BEGIN_ALLOW_THREADS
12718 success = FindNextFileW(iterator->handle, file_data);
12719 Py_END_ALLOW_THREADS
12720 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012721 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012722 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012723 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012724 break;
12725 }
12726 }
12727 iterator->first_time = 0;
12728
12729 /* Skip over . and .. */
12730 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012731 wcscmp(file_data->cFileName, L"..") != 0) {
12732 entry = DirEntry_from_find_data(&iterator->path, file_data);
12733 if (!entry)
12734 break;
12735 return entry;
12736 }
Victor Stinner6036e442015-03-08 01:58:04 +010012737
12738 /* Loop till we get a non-dot directory or finish iterating */
12739 }
12740
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012741 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012742 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012743 return NULL;
12744}
12745
12746#else /* POSIX */
12747
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012748static int
12749ScandirIterator_is_closed(ScandirIterator *iterator)
12750{
12751 return !iterator->dirp;
12752}
12753
Victor Stinner6036e442015-03-08 01:58:04 +010012754static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012755ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012756{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012757 DIR *dirp = iterator->dirp;
12758
12759 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012760 return;
12761
Victor Stinner6036e442015-03-08 01:58:04 +010012762 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012763 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012764#ifdef HAVE_FDOPENDIR
12765 if (iterator->path.fd != -1)
12766 rewinddir(dirp);
12767#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012768 closedir(dirp);
12769 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012770 return;
12771}
12772
12773static PyObject *
12774ScandirIterator_iternext(ScandirIterator *iterator)
12775{
12776 struct dirent *direntp;
12777 Py_ssize_t name_len;
12778 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012779 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012780
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012781 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012782 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012783 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012784
12785 while (1) {
12786 errno = 0;
12787 Py_BEGIN_ALLOW_THREADS
12788 direntp = readdir(iterator->dirp);
12789 Py_END_ALLOW_THREADS
12790
12791 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012792 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012793 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012794 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012795 break;
12796 }
12797
12798 /* Skip over . and .. */
12799 name_len = NAMLEN(direntp);
12800 is_dot = direntp->d_name[0] == '.' &&
12801 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12802 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012803 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012804 name_len, direntp->d_ino
12805#ifdef HAVE_DIRENT_D_TYPE
12806 , direntp->d_type
12807#endif
12808 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012809 if (!entry)
12810 break;
12811 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012812 }
12813
12814 /* Loop till we get a non-dot directory or finish iterating */
12815 }
12816
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012817 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012818 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012819 return NULL;
12820}
12821
12822#endif
12823
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012824static PyObject *
12825ScandirIterator_close(ScandirIterator *self, PyObject *args)
12826{
12827 ScandirIterator_closedir(self);
12828 Py_RETURN_NONE;
12829}
12830
12831static PyObject *
12832ScandirIterator_enter(PyObject *self, PyObject *args)
12833{
12834 Py_INCREF(self);
12835 return self;
12836}
12837
12838static PyObject *
12839ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12840{
12841 ScandirIterator_closedir(self);
12842 Py_RETURN_NONE;
12843}
12844
Victor Stinner6036e442015-03-08 01:58:04 +010012845static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012846ScandirIterator_finalize(ScandirIterator *iterator)
12847{
12848 PyObject *error_type, *error_value, *error_traceback;
12849
12850 /* Save the current exception, if any. */
12851 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12852
12853 if (!ScandirIterator_is_closed(iterator)) {
12854 ScandirIterator_closedir(iterator);
12855
12856 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12857 "unclosed scandir iterator %R", iterator)) {
12858 /* Spurious errors can appear at shutdown */
12859 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12860 PyErr_WriteUnraisable((PyObject *) iterator);
12861 }
12862 }
12863 }
12864
Victor Stinner7bfa4092016-03-23 00:43:54 +010012865 path_cleanup(&iterator->path);
12866
12867 /* Restore the saved exception. */
12868 PyErr_Restore(error_type, error_value, error_traceback);
12869}
12870
12871static void
Victor Stinner6036e442015-03-08 01:58:04 +010012872ScandirIterator_dealloc(ScandirIterator *iterator)
12873{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012874 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12875 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012876
Victor Stinner6036e442015-03-08 01:58:04 +010012877 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12878}
12879
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012880static PyMethodDef ScandirIterator_methods[] = {
12881 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12882 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12883 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12884 {NULL}
12885};
12886
Benjamin Peterson5646de42015-04-12 17:56:34 -040012887static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012888 PyVarObject_HEAD_INIT(NULL, 0)
12889 MODNAME ".ScandirIterator", /* tp_name */
12890 sizeof(ScandirIterator), /* tp_basicsize */
12891 0, /* tp_itemsize */
12892 /* methods */
12893 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12894 0, /* tp_print */
12895 0, /* tp_getattr */
12896 0, /* tp_setattr */
12897 0, /* tp_compare */
12898 0, /* tp_repr */
12899 0, /* tp_as_number */
12900 0, /* tp_as_sequence */
12901 0, /* tp_as_mapping */
12902 0, /* tp_hash */
12903 0, /* tp_call */
12904 0, /* tp_str */
12905 0, /* tp_getattro */
12906 0, /* tp_setattro */
12907 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012908 Py_TPFLAGS_DEFAULT
12909 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012910 0, /* tp_doc */
12911 0, /* tp_traverse */
12912 0, /* tp_clear */
12913 0, /* tp_richcompare */
12914 0, /* tp_weaklistoffset */
12915 PyObject_SelfIter, /* tp_iter */
12916 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012917 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012918 0, /* tp_members */
12919 0, /* tp_getset */
12920 0, /* tp_base */
12921 0, /* tp_dict */
12922 0, /* tp_descr_get */
12923 0, /* tp_descr_set */
12924 0, /* tp_dictoffset */
12925 0, /* tp_init */
12926 0, /* tp_alloc */
12927 0, /* tp_new */
12928 0, /* tp_free */
12929 0, /* tp_is_gc */
12930 0, /* tp_bases */
12931 0, /* tp_mro */
12932 0, /* tp_cache */
12933 0, /* tp_subclasses */
12934 0, /* tp_weaklist */
12935 0, /* tp_del */
12936 0, /* tp_version_tag */
12937 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012938};
12939
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012940/*[clinic input]
12941os.scandir
12942
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012943 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012944
12945Return an iterator of DirEntry objects for given path.
12946
BNMetricsb9427072018-11-02 15:20:19 +000012947path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012948is bytes, the names of yielded DirEntry objects will also be bytes; in
12949all other circumstances they will be str.
12950
12951If path is None, uses the path='.'.
12952[clinic start generated code]*/
12953
Victor Stinner6036e442015-03-08 01:58:04 +010012954static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012955os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000012956/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012957{
12958 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012959#ifdef MS_WINDOWS
12960 wchar_t *path_strW;
12961#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012962 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012963#ifdef HAVE_FDOPENDIR
12964 int fd = -1;
12965#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012966#endif
12967
12968 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12969 if (!iterator)
12970 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012971
12972#ifdef MS_WINDOWS
12973 iterator->handle = INVALID_HANDLE_VALUE;
12974#else
12975 iterator->dirp = NULL;
12976#endif
12977
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012978 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012979 /* Move the ownership to iterator->path */
12980 path->object = NULL;
12981 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012982
12983#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012984 iterator->first_time = 1;
12985
12986 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12987 if (!path_strW)
12988 goto error;
12989
12990 Py_BEGIN_ALLOW_THREADS
12991 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12992 Py_END_ALLOW_THREADS
12993
12994 PyMem_Free(path_strW);
12995
12996 if (iterator->handle == INVALID_HANDLE_VALUE) {
12997 path_error(&iterator->path);
12998 goto error;
12999 }
13000#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013001 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013002#ifdef HAVE_FDOPENDIR
13003 if (path->fd != -1) {
13004 /* closedir() closes the FD, so we duplicate it */
13005 fd = _Py_dup(path->fd);
13006 if (fd == -1)
13007 goto error;
13008
13009 Py_BEGIN_ALLOW_THREADS
13010 iterator->dirp = fdopendir(fd);
13011 Py_END_ALLOW_THREADS
13012 }
13013 else
13014#endif
13015 {
13016 if (iterator->path.narrow)
13017 path_str = iterator->path.narrow;
13018 else
13019 path_str = ".";
13020
13021 Py_BEGIN_ALLOW_THREADS
13022 iterator->dirp = opendir(path_str);
13023 Py_END_ALLOW_THREADS
13024 }
Victor Stinner6036e442015-03-08 01:58:04 +010013025
13026 if (!iterator->dirp) {
13027 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013028#ifdef HAVE_FDOPENDIR
13029 if (fd != -1) {
13030 Py_BEGIN_ALLOW_THREADS
13031 close(fd);
13032 Py_END_ALLOW_THREADS
13033 }
13034#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013035 goto error;
13036 }
13037#endif
13038
13039 return (PyObject *)iterator;
13040
13041error:
13042 Py_DECREF(iterator);
13043 return NULL;
13044}
13045
Ethan Furman410ef8e2016-06-04 12:06:26 -070013046/*
13047 Return the file system path representation of the object.
13048
13049 If the object is str or bytes, then allow it to pass through with
13050 an incremented refcount. If the object defines __fspath__(), then
13051 return the result of that method. All other types raise a TypeError.
13052*/
13053PyObject *
13054PyOS_FSPath(PyObject *path)
13055{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013056 /* For error message reasons, this function is manually inlined in
13057 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013058 _Py_IDENTIFIER(__fspath__);
13059 PyObject *func = NULL;
13060 PyObject *path_repr = NULL;
13061
13062 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13063 Py_INCREF(path);
13064 return path;
13065 }
13066
13067 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13068 if (NULL == func) {
13069 return PyErr_Format(PyExc_TypeError,
13070 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013071 "not %.200s",
13072 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013073 }
13074
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013075 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013076 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013077 if (NULL == path_repr) {
13078 return NULL;
13079 }
13080
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013081 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13082 PyErr_Format(PyExc_TypeError,
13083 "expected %.200s.__fspath__() to return str or bytes, "
13084 "not %.200s", Py_TYPE(path)->tp_name,
13085 Py_TYPE(path_repr)->tp_name);
13086 Py_DECREF(path_repr);
13087 return NULL;
13088 }
13089
Ethan Furman410ef8e2016-06-04 12:06:26 -070013090 return path_repr;
13091}
13092
13093/*[clinic input]
13094os.fspath
13095
13096 path: object
13097
13098Return the file system path representation of the object.
13099
Brett Cannonb4f43e92016-06-09 14:32:08 -070013100If the object is str or bytes, then allow it to pass through as-is. If the
13101object defines __fspath__(), then return the result of that method. All other
13102types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013103[clinic start generated code]*/
13104
13105static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013106os_fspath_impl(PyObject *module, PyObject *path)
13107/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013108{
13109 return PyOS_FSPath(path);
13110}
Victor Stinner6036e442015-03-08 01:58:04 +010013111
Victor Stinner9b1f4742016-09-06 16:18:52 -070013112#ifdef HAVE_GETRANDOM_SYSCALL
13113/*[clinic input]
13114os.getrandom
13115
13116 size: Py_ssize_t
13117 flags: int=0
13118
13119Obtain a series of random bytes.
13120[clinic start generated code]*/
13121
13122static PyObject *
13123os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13124/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13125{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013126 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013127 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013128
13129 if (size < 0) {
13130 errno = EINVAL;
13131 return posix_error();
13132 }
13133
Victor Stinnerec2319c2016-09-20 23:00:59 +020013134 bytes = PyBytes_FromStringAndSize(NULL, size);
13135 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013136 PyErr_NoMemory();
13137 return NULL;
13138 }
13139
13140 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013141 n = syscall(SYS_getrandom,
13142 PyBytes_AS_STRING(bytes),
13143 PyBytes_GET_SIZE(bytes),
13144 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013145 if (n < 0 && errno == EINTR) {
13146 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013147 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013148 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013149
13150 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013151 continue;
13152 }
13153 break;
13154 }
13155
13156 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013157 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013158 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013159 }
13160
Victor Stinnerec2319c2016-09-20 23:00:59 +020013161 if (n != size) {
13162 _PyBytes_Resize(&bytes, n);
13163 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013164
13165 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013166
13167error:
13168 Py_DECREF(bytes);
13169 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013170}
13171#endif /* HAVE_GETRANDOM_SYSCALL */
13172
Steve Dower2438cdf2019-03-29 16:37:16 -070013173#ifdef MS_WINDOWS
13174/* bpo-36085: Helper functions for managing DLL search directories
13175 * on win32
13176 */
13177
13178typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13179typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13180
13181/*[clinic input]
13182os._add_dll_directory
13183
13184 path: path_t
13185
13186Add a path to the DLL search path.
13187
13188This search path is used when resolving dependencies for imported
13189extension modules (the module itself is resolved through sys.path),
13190and also by ctypes.
13191
13192Returns an opaque value that may be passed to os.remove_dll_directory
13193to remove this directory from the search path.
13194[clinic start generated code]*/
13195
13196static PyObject *
13197os__add_dll_directory_impl(PyObject *module, path_t *path)
13198/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13199{
13200 HMODULE hKernel32;
13201 PAddDllDirectory AddDllDirectory;
13202 DLL_DIRECTORY_COOKIE cookie = 0;
13203 DWORD err = 0;
13204
13205 /* For Windows 7, we have to load this. As this will be a fairly
13206 infrequent operation, just do it each time. Kernel32 is always
13207 loaded. */
13208 Py_BEGIN_ALLOW_THREADS
13209 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13210 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13211 hKernel32, "AddDllDirectory")) ||
13212 !(cookie = (*AddDllDirectory)(path->wide))) {
13213 err = GetLastError();
13214 }
13215 Py_END_ALLOW_THREADS
13216
13217 if (err) {
13218 return win32_error_object_err("add_dll_directory",
13219 path->object, err);
13220 }
13221
13222 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13223}
13224
13225/*[clinic input]
13226os._remove_dll_directory
13227
13228 cookie: object
13229
13230Removes a path from the DLL search path.
13231
13232The parameter is an opaque value that was returned from
13233os.add_dll_directory. You can only remove directories that you added
13234yourself.
13235[clinic start generated code]*/
13236
13237static PyObject *
13238os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13239/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13240{
13241 HMODULE hKernel32;
13242 PRemoveDllDirectory RemoveDllDirectory;
13243 DLL_DIRECTORY_COOKIE cookieValue;
13244 DWORD err = 0;
13245
13246 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13247 PyErr_SetString(PyExc_TypeError,
13248 "Provided cookie was not returned from os.add_dll_directory");
13249 return NULL;
13250 }
13251
13252 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13253 cookie, "DLL directory cookie");
13254
13255 /* For Windows 7, we have to load this. As this will be a fairly
13256 infrequent operation, just do it each time. Kernel32 is always
13257 loaded. */
13258 Py_BEGIN_ALLOW_THREADS
13259 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13260 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13261 hKernel32, "RemoveDllDirectory")) ||
13262 !(*RemoveDllDirectory)(cookieValue)) {
13263 err = GetLastError();
13264 }
13265 Py_END_ALLOW_THREADS
13266
13267 if (err) {
13268 return win32_error_object_err("remove_dll_directory",
13269 NULL, err);
13270 }
13271
13272 if (PyCapsule_SetName(cookie, NULL)) {
13273 return NULL;
13274 }
13275
13276 Py_RETURN_NONE;
13277}
13278
13279#endif
Larry Hastings31826802013-10-19 00:09:25 -070013280
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013281static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013282
13283 OS_STAT_METHODDEF
13284 OS_ACCESS_METHODDEF
13285 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013286 OS_CHDIR_METHODDEF
13287 OS_CHFLAGS_METHODDEF
13288 OS_CHMOD_METHODDEF
13289 OS_FCHMOD_METHODDEF
13290 OS_LCHMOD_METHODDEF
13291 OS_CHOWN_METHODDEF
13292 OS_FCHOWN_METHODDEF
13293 OS_LCHOWN_METHODDEF
13294 OS_LCHFLAGS_METHODDEF
13295 OS_CHROOT_METHODDEF
13296 OS_CTERMID_METHODDEF
13297 OS_GETCWD_METHODDEF
13298 OS_GETCWDB_METHODDEF
13299 OS_LINK_METHODDEF
13300 OS_LISTDIR_METHODDEF
13301 OS_LSTAT_METHODDEF
13302 OS_MKDIR_METHODDEF
13303 OS_NICE_METHODDEF
13304 OS_GETPRIORITY_METHODDEF
13305 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013306 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013307 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013308 OS_READLINK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013309 OS_RENAME_METHODDEF
13310 OS_REPLACE_METHODDEF
13311 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013312 OS_SYMLINK_METHODDEF
13313 OS_SYSTEM_METHODDEF
13314 OS_UMASK_METHODDEF
13315 OS_UNAME_METHODDEF
13316 OS_UNLINK_METHODDEF
13317 OS_REMOVE_METHODDEF
13318 OS_UTIME_METHODDEF
13319 OS_TIMES_METHODDEF
13320 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013321 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013322 OS_EXECV_METHODDEF
13323 OS_EXECVE_METHODDEF
13324 OS_SPAWNV_METHODDEF
13325 OS_SPAWNVE_METHODDEF
13326 OS_FORK1_METHODDEF
13327 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013328 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013329 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13330 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13331 OS_SCHED_GETPARAM_METHODDEF
13332 OS_SCHED_GETSCHEDULER_METHODDEF
13333 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13334 OS_SCHED_SETPARAM_METHODDEF
13335 OS_SCHED_SETSCHEDULER_METHODDEF
13336 OS_SCHED_YIELD_METHODDEF
13337 OS_SCHED_SETAFFINITY_METHODDEF
13338 OS_SCHED_GETAFFINITY_METHODDEF
13339 OS_OPENPTY_METHODDEF
13340 OS_FORKPTY_METHODDEF
13341 OS_GETEGID_METHODDEF
13342 OS_GETEUID_METHODDEF
13343 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013344#ifdef HAVE_GETGROUPLIST
13345 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13346#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013347 OS_GETGROUPS_METHODDEF
13348 OS_GETPID_METHODDEF
13349 OS_GETPGRP_METHODDEF
13350 OS_GETPPID_METHODDEF
13351 OS_GETUID_METHODDEF
13352 OS_GETLOGIN_METHODDEF
13353 OS_KILL_METHODDEF
13354 OS_KILLPG_METHODDEF
13355 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013356#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013357 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013358#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013359 OS_SETUID_METHODDEF
13360 OS_SETEUID_METHODDEF
13361 OS_SETREUID_METHODDEF
13362 OS_SETGID_METHODDEF
13363 OS_SETEGID_METHODDEF
13364 OS_SETREGID_METHODDEF
13365 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013366#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013367 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013368#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013369 OS_GETPGID_METHODDEF
13370 OS_SETPGRP_METHODDEF
13371 OS_WAIT_METHODDEF
13372 OS_WAIT3_METHODDEF
13373 OS_WAIT4_METHODDEF
13374 OS_WAITID_METHODDEF
13375 OS_WAITPID_METHODDEF
13376 OS_GETSID_METHODDEF
13377 OS_SETSID_METHODDEF
13378 OS_SETPGID_METHODDEF
13379 OS_TCGETPGRP_METHODDEF
13380 OS_TCSETPGRP_METHODDEF
13381 OS_OPEN_METHODDEF
13382 OS_CLOSE_METHODDEF
13383 OS_CLOSERANGE_METHODDEF
13384 OS_DEVICE_ENCODING_METHODDEF
13385 OS_DUP_METHODDEF
13386 OS_DUP2_METHODDEF
13387 OS_LOCKF_METHODDEF
13388 OS_LSEEK_METHODDEF
13389 OS_READ_METHODDEF
13390 OS_READV_METHODDEF
13391 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013392 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013393 OS_WRITE_METHODDEF
13394 OS_WRITEV_METHODDEF
13395 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013396 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013397#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013398 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013399 posix_sendfile__doc__},
13400#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013401 OS_FSTAT_METHODDEF
13402 OS_ISATTY_METHODDEF
13403 OS_PIPE_METHODDEF
13404 OS_PIPE2_METHODDEF
13405 OS_MKFIFO_METHODDEF
13406 OS_MKNOD_METHODDEF
13407 OS_MAJOR_METHODDEF
13408 OS_MINOR_METHODDEF
13409 OS_MAKEDEV_METHODDEF
13410 OS_FTRUNCATE_METHODDEF
13411 OS_TRUNCATE_METHODDEF
13412 OS_POSIX_FALLOCATE_METHODDEF
13413 OS_POSIX_FADVISE_METHODDEF
13414 OS_PUTENV_METHODDEF
13415 OS_UNSETENV_METHODDEF
13416 OS_STRERROR_METHODDEF
13417 OS_FCHDIR_METHODDEF
13418 OS_FSYNC_METHODDEF
13419 OS_SYNC_METHODDEF
13420 OS_FDATASYNC_METHODDEF
13421 OS_WCOREDUMP_METHODDEF
13422 OS_WIFCONTINUED_METHODDEF
13423 OS_WIFSTOPPED_METHODDEF
13424 OS_WIFSIGNALED_METHODDEF
13425 OS_WIFEXITED_METHODDEF
13426 OS_WEXITSTATUS_METHODDEF
13427 OS_WTERMSIG_METHODDEF
13428 OS_WSTOPSIG_METHODDEF
13429 OS_FSTATVFS_METHODDEF
13430 OS_STATVFS_METHODDEF
13431 OS_CONFSTR_METHODDEF
13432 OS_SYSCONF_METHODDEF
13433 OS_FPATHCONF_METHODDEF
13434 OS_PATHCONF_METHODDEF
13435 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013436 OS__GETFULLPATHNAME_METHODDEF
13437 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013438 OS__GETDISKUSAGE_METHODDEF
13439 OS__GETFINALPATHNAME_METHODDEF
13440 OS__GETVOLUMEPATHNAME_METHODDEF
13441 OS_GETLOADAVG_METHODDEF
13442 OS_URANDOM_METHODDEF
13443 OS_SETRESUID_METHODDEF
13444 OS_SETRESGID_METHODDEF
13445 OS_GETRESUID_METHODDEF
13446 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013447
Larry Hastings2f936352014-08-05 14:04:04 +100013448 OS_GETXATTR_METHODDEF
13449 OS_SETXATTR_METHODDEF
13450 OS_REMOVEXATTR_METHODDEF
13451 OS_LISTXATTR_METHODDEF
13452
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013453#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13454 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13455#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013456 OS_CPU_COUNT_METHODDEF
13457 OS_GET_INHERITABLE_METHODDEF
13458 OS_SET_INHERITABLE_METHODDEF
13459 OS_GET_HANDLE_INHERITABLE_METHODDEF
13460 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013461#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013462 OS_GET_BLOCKING_METHODDEF
13463 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013464#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013465 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013466 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013467 OS_GETRANDOM_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070013468#ifdef MS_WINDOWS
13469 OS__ADD_DLL_DIRECTORY_METHODDEF
13470 OS__REMOVE_DLL_DIRECTORY_METHODDEF
13471#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013472 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013473};
13474
Barry Warsaw4a342091996-12-19 23:50:02 +000013475static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013476all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013477{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013478#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013479 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013480#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013481#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013482 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013483#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013484#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013485 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013486#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013487#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013488 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013489#endif
Fred Drakec9680921999-12-13 16:37:25 +000013490#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013491 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013492#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013493#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013494 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013495#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013496#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013497 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013498#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013499#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013500 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013501#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013502#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013503 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013504#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013505#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013506 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013507#endif
13508#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013509 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013510#endif
13511#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013512 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013513#endif
13514#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013515 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013516#endif
13517#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013518 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013519#endif
13520#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013521 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013522#endif
13523#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013524 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013525#endif
13526#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013527 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013528#endif
13529#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013530 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013531#endif
13532#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013533 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013534#endif
13535#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013536 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013537#endif
13538#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013539 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013540#endif
13541#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013542 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013543#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013544#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013545 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013546#endif
13547#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013548 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013549#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013550#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013551 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013552#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013553#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013554 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013555#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013556#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013557#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013558 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013559#endif
13560#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013561 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013562#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013563#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013564#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013565 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013566#endif
13567#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013568 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013569#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013570#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013571 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013572#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013573#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013574 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013575#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013576#ifdef O_TMPFILE
13577 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13578#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013579#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013580 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013581#endif
13582#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013583 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013584#endif
13585#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013586 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013587#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013588#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013589 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013590#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013591#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013592 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013593#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013594
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013595
Jesus Cea94363612012-06-22 18:32:07 +020013596#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013597 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013598#endif
13599#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013600 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013601#endif
13602
Tim Peters5aa91602002-01-30 05:46:57 +000013603/* MS Windows */
13604#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013605 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013606 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013607#endif
13608#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013609 /* Optimize for short life (keep in memory). */
13610 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013611 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013612#endif
13613#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013614 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013615 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013616#endif
13617#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013618 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013619 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013620#endif
13621#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013622 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013623 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013624#endif
13625
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013626/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013627#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013628 /* Send a SIGIO signal whenever input or output
13629 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013630 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013631#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013632#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013633 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013634 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013635#endif
13636#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013637 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013638 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013639#endif
13640#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013641 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013642 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013643#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013644#ifdef O_NOLINKS
13645 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013646 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013647#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013648#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013649 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013650 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013651#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013652
Victor Stinner8c62be82010-05-06 00:08:46 +000013653 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013654#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013655 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013656#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013657#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013658 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013659#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013660#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013661 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013662#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013663#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013664 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013665#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013666#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013667 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013668#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013669#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013670 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013671#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013672#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013673 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013674#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013675#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013676 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013677#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013678#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013679 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013680#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013681#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013682 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013683#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013684#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013685 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013686#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013687#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013688 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013689#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013690#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013691 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013692#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013693#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013694 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013695#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013696#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013697 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013698#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013699#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013700 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013701#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013702#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013703 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013704#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013705
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013706 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013707#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013708 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013709#endif /* ST_RDONLY */
13710#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013711 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013712#endif /* ST_NOSUID */
13713
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013714 /* GNU extensions */
13715#ifdef ST_NODEV
13716 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13717#endif /* ST_NODEV */
13718#ifdef ST_NOEXEC
13719 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13720#endif /* ST_NOEXEC */
13721#ifdef ST_SYNCHRONOUS
13722 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13723#endif /* ST_SYNCHRONOUS */
13724#ifdef ST_MANDLOCK
13725 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13726#endif /* ST_MANDLOCK */
13727#ifdef ST_WRITE
13728 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13729#endif /* ST_WRITE */
13730#ifdef ST_APPEND
13731 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13732#endif /* ST_APPEND */
13733#ifdef ST_NOATIME
13734 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13735#endif /* ST_NOATIME */
13736#ifdef ST_NODIRATIME
13737 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13738#endif /* ST_NODIRATIME */
13739#ifdef ST_RELATIME
13740 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13741#endif /* ST_RELATIME */
13742
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013743 /* FreeBSD sendfile() constants */
13744#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013745 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013746#endif
13747#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013748 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013749#endif
13750#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013751 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013752#endif
13753
Ross Lagerwall7807c352011-03-17 20:20:30 +020013754 /* constants for posix_fadvise */
13755#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013756 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013757#endif
13758#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013759 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013760#endif
13761#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013762 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013763#endif
13764#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013765 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013766#endif
13767#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013768 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013769#endif
13770#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013771 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013772#endif
13773
13774 /* constants for waitid */
13775#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013776 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13777 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13778 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013779#endif
13780#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013781 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013782#endif
13783#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013784 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013785#endif
13786#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013787 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013788#endif
13789#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013790 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013791#endif
13792#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013793 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013794#endif
13795#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013796 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013797#endif
13798#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013799 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013800#endif
13801
13802 /* constants for lockf */
13803#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013804 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013805#endif
13806#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013807 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013808#endif
13809#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013810 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013811#endif
13812#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013813 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013814#endif
13815
Pablo Galindo4defba32018-01-27 16:16:37 +000013816#ifdef RWF_DSYNC
13817 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13818#endif
13819#ifdef RWF_HIPRI
13820 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13821#endif
13822#ifdef RWF_SYNC
13823 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13824#endif
13825#ifdef RWF_NOWAIT
13826 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13827#endif
13828
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013829/* constants for posix_spawn */
13830#ifdef HAVE_POSIX_SPAWN
13831 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
13832 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
13833 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
13834#endif
13835
Guido van Rossum246bc171999-02-01 23:54:31 +000013836#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013837 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13838 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13839 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13840 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13841 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013842#endif
13843
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013844#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013845#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013846 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013847#endif
13848#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013849 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013850#endif
13851#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013852 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013853#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013854#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013855 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013856#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013857#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013858 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013859#endif
13860#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013861 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013862#endif
13863#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013864 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013865#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013866#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013867 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013868#endif
13869#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013870 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013871#endif
13872#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013873 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013874#endif
13875#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013876 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013877#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013878#endif
13879
Benjamin Peterson9428d532011-09-14 11:45:52 -040013880#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013881 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13882 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13883 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013884#endif
13885
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013886#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013887 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013888#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013889#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013890 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013891#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013892#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013893 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013894#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013895#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013896 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013897#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013898#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013899 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013900#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013901#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013902 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013903#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013904#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013905 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013906#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013907#if HAVE_DECL_RTLD_MEMBER
13908 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13909#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013910
Victor Stinner9b1f4742016-09-06 16:18:52 -070013911#ifdef HAVE_GETRANDOM_SYSCALL
13912 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13913 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13914#endif
13915
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013916#if defined(__APPLE__)
13917 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
13918#endif
13919
Steve Dower2438cdf2019-03-29 16:37:16 -070013920#ifdef MS_WINDOWS
13921 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
13922 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
13923 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
13924 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
13925 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
13926#endif
13927
Victor Stinner8c62be82010-05-06 00:08:46 +000013928 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013929}
13930
13931
Martin v. Löwis1a214512008-06-11 05:26:20 +000013932static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013933 PyModuleDef_HEAD_INIT,
13934 MODNAME,
13935 posix__doc__,
13936 -1,
13937 posix_methods,
13938 NULL,
13939 NULL,
13940 NULL,
13941 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013942};
13943
13944
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013945static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013946
13947#ifdef HAVE_FACCESSAT
13948 "HAVE_FACCESSAT",
13949#endif
13950
13951#ifdef HAVE_FCHDIR
13952 "HAVE_FCHDIR",
13953#endif
13954
13955#ifdef HAVE_FCHMOD
13956 "HAVE_FCHMOD",
13957#endif
13958
13959#ifdef HAVE_FCHMODAT
13960 "HAVE_FCHMODAT",
13961#endif
13962
13963#ifdef HAVE_FCHOWN
13964 "HAVE_FCHOWN",
13965#endif
13966
Larry Hastings00964ed2013-08-12 13:49:30 -040013967#ifdef HAVE_FCHOWNAT
13968 "HAVE_FCHOWNAT",
13969#endif
13970
Larry Hastings9cf065c2012-06-22 16:30:09 -070013971#ifdef HAVE_FEXECVE
13972 "HAVE_FEXECVE",
13973#endif
13974
13975#ifdef HAVE_FDOPENDIR
13976 "HAVE_FDOPENDIR",
13977#endif
13978
Georg Brandl306336b2012-06-24 12:55:33 +020013979#ifdef HAVE_FPATHCONF
13980 "HAVE_FPATHCONF",
13981#endif
13982
Larry Hastings9cf065c2012-06-22 16:30:09 -070013983#ifdef HAVE_FSTATAT
13984 "HAVE_FSTATAT",
13985#endif
13986
13987#ifdef HAVE_FSTATVFS
13988 "HAVE_FSTATVFS",
13989#endif
13990
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013991#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013992 "HAVE_FTRUNCATE",
13993#endif
13994
Larry Hastings9cf065c2012-06-22 16:30:09 -070013995#ifdef HAVE_FUTIMENS
13996 "HAVE_FUTIMENS",
13997#endif
13998
13999#ifdef HAVE_FUTIMES
14000 "HAVE_FUTIMES",
14001#endif
14002
14003#ifdef HAVE_FUTIMESAT
14004 "HAVE_FUTIMESAT",
14005#endif
14006
14007#ifdef HAVE_LINKAT
14008 "HAVE_LINKAT",
14009#endif
14010
14011#ifdef HAVE_LCHFLAGS
14012 "HAVE_LCHFLAGS",
14013#endif
14014
14015#ifdef HAVE_LCHMOD
14016 "HAVE_LCHMOD",
14017#endif
14018
14019#ifdef HAVE_LCHOWN
14020 "HAVE_LCHOWN",
14021#endif
14022
14023#ifdef HAVE_LSTAT
14024 "HAVE_LSTAT",
14025#endif
14026
14027#ifdef HAVE_LUTIMES
14028 "HAVE_LUTIMES",
14029#endif
14030
14031#ifdef HAVE_MKDIRAT
14032 "HAVE_MKDIRAT",
14033#endif
14034
14035#ifdef HAVE_MKFIFOAT
14036 "HAVE_MKFIFOAT",
14037#endif
14038
14039#ifdef HAVE_MKNODAT
14040 "HAVE_MKNODAT",
14041#endif
14042
14043#ifdef HAVE_OPENAT
14044 "HAVE_OPENAT",
14045#endif
14046
14047#ifdef HAVE_READLINKAT
14048 "HAVE_READLINKAT",
14049#endif
14050
14051#ifdef HAVE_RENAMEAT
14052 "HAVE_RENAMEAT",
14053#endif
14054
14055#ifdef HAVE_SYMLINKAT
14056 "HAVE_SYMLINKAT",
14057#endif
14058
14059#ifdef HAVE_UNLINKAT
14060 "HAVE_UNLINKAT",
14061#endif
14062
14063#ifdef HAVE_UTIMENSAT
14064 "HAVE_UTIMENSAT",
14065#endif
14066
14067#ifdef MS_WINDOWS
14068 "MS_WINDOWS",
14069#endif
14070
14071 NULL
14072};
14073
14074
Mark Hammondfe51c6d2002-08-02 02:27:13 +000014075PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000014076INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014077{
Victor Stinner8c62be82010-05-06 00:08:46 +000014078 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014079 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014080 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014081
Victor Stinner8c62be82010-05-06 00:08:46 +000014082 m = PyModule_Create(&posixmodule);
14083 if (m == NULL)
14084 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000014085
Victor Stinner8c62be82010-05-06 00:08:46 +000014086 /* Initialize environ dictionary */
14087 v = convertenviron();
14088 Py_XINCREF(v);
14089 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
14090 return NULL;
14091 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014092
Victor Stinner8c62be82010-05-06 00:08:46 +000014093 if (all_ins(m))
14094 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000014095
Victor Stinner8c62be82010-05-06 00:08:46 +000014096 if (setup_confname_tables(m))
14097 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014098
Victor Stinner8c62be82010-05-06 00:08:46 +000014099 Py_INCREF(PyExc_OSError);
14100 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014101
Guido van Rossumb3d39562000-01-31 18:41:26 +000014102#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000014103 if (posix_putenv_garbage == NULL)
14104 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014105#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014106
Victor Stinner8c62be82010-05-06 00:08:46 +000014107 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020014108#if defined(HAVE_WAITID) && !defined(__APPLE__)
14109 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014110 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
14111 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014112 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014113 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014114#endif
14115
Christian Heimes25827622013-10-12 01:27:08 +020014116 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000014117 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14118 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14119 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014120 StatResultType = PyStructSequence_NewType(&stat_result_desc);
14121 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014122 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014123 }
14124 structseq_new = StatResultType->tp_new;
14125 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014126
Christian Heimes25827622013-10-12 01:27:08 +020014127 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014128 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
14129 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014130 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014131 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014132#ifdef NEED_TICKS_PER_SECOND
14133# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000014134 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014135# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000014136 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014137# else
Victor Stinner8c62be82010-05-06 00:08:46 +000014138 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014139# endif
14140#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014141
William Orr81574b82018-10-01 22:19:56 -070014142#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014143 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014144 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
14145 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014146 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014147 }
14148 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014149#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014150
14151 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014152 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
14153 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014154 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014155 }
Victor Stinner6036e442015-03-08 01:58:04 +010014156
14157 /* initialize scandir types */
14158 if (PyType_Ready(&ScandirIteratorType) < 0)
14159 return NULL;
14160 if (PyType_Ready(&DirEntryType) < 0)
14161 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014162 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014163#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014164 Py_INCREF((PyObject*) WaitidResultType);
14165 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020014166#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014167 Py_INCREF((PyObject*) StatResultType);
14168 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
14169 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000014170 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014171 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014172
14173#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014174 Py_INCREF(SchedParamType);
14175 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014176#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014177
Larry Hastings605a62d2012-06-24 04:33:36 -070014178 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014179 TimesResultType = PyStructSequence_NewType(&times_result_desc);
14180 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014181 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014182 }
14183 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014184
14185 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014186 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
14187 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014188 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014189 }
14190 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014191
Thomas Wouters477c8d52006-05-27 19:21:47 +000014192#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014193 /*
14194 * Step 2 of weak-linking support on Mac OS X.
14195 *
14196 * The code below removes functions that are not available on the
14197 * currently active platform.
14198 *
14199 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014200 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014201 * OSX 10.4.
14202 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014203#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014204 if (fstatvfs == NULL) {
14205 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14206 return NULL;
14207 }
14208 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014209#endif /* HAVE_FSTATVFS */
14210
14211#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014212 if (statvfs == NULL) {
14213 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14214 return NULL;
14215 }
14216 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014217#endif /* HAVE_STATVFS */
14218
14219# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014220 if (lchown == NULL) {
14221 if (PyObject_DelAttrString(m, "lchown") == -1) {
14222 return NULL;
14223 }
14224 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014225#endif /* HAVE_LCHOWN */
14226
14227
14228#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014229
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014230 Py_INCREF(TerminalSizeType);
14231 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014232
Larry Hastings6fe20b32012-04-19 15:07:49 -070014233 billion = PyLong_FromLong(1000000000);
14234 if (!billion)
14235 return NULL;
14236
Larry Hastings9cf065c2012-06-22 16:30:09 -070014237 /* suppress "function not used" warnings */
14238 {
14239 int ignored;
14240 fd_specified("", -1);
14241 follow_symlinks_specified("", 1);
14242 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14243 dir_fd_converter(Py_None, &ignored);
14244 dir_fd_unavailable(Py_None, &ignored);
14245 }
14246
14247 /*
14248 * provide list of locally available functions
14249 * so os.py can populate support_* lists
14250 */
14251 list = PyList_New(0);
14252 if (!list)
14253 return NULL;
14254 for (trace = have_functions; *trace; trace++) {
14255 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14256 if (!unicode)
14257 return NULL;
14258 if (PyList_Append(list, unicode))
14259 return NULL;
14260 Py_DECREF(unicode);
14261 }
14262 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014263
14264 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014265 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014266
14267 initialized = 1;
14268
Victor Stinner8c62be82010-05-06 00:08:46 +000014269 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014270}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014271
14272#ifdef __cplusplus
14273}
14274#endif