blob: 56ec3ee5a0eed3422d2a6b7f9ef7ef8eeddea11c [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
1262 if (sigemptyset(mask)) {
1263 /* Probably only if mask == NULL. */
1264 PyErr_SetFromErrno(PyExc_OSError);
1265 return 0;
1266 }
1267
1268 iterator = PyObject_GetIter(obj);
1269 if (iterator == NULL) {
1270 return 0;
1271 }
1272
1273 while ((item = PyIter_Next(iterator)) != NULL) {
1274 signum = PyLong_AsLongAndOverflow(item, &overflow);
1275 Py_DECREF(item);
1276 if (signum <= 0 || signum >= NSIG) {
1277 if (overflow || signum != -1 || !PyErr_Occurred()) {
1278 PyErr_Format(PyExc_ValueError,
1279 "signal number %ld out of range", signum);
1280 }
1281 goto error;
1282 }
1283 if (sigaddset(mask, (int)signum)) {
1284 if (errno != EINVAL) {
1285 /* Probably impossible */
1286 PyErr_SetFromErrno(PyExc_OSError);
1287 goto error;
1288 }
1289 /* For backwards compatibility, allow idioms such as
1290 * `range(1, NSIG)` but warn about invalid signal numbers
1291 */
1292 const char msg[] =
1293 "invalid signal number %ld, please use valid_signals()";
1294 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1295 goto error;
1296 }
1297 }
1298 }
1299 if (!PyErr_Occurred()) {
1300 Py_DECREF(iterator);
1301 return 1;
1302 }
1303
1304error:
1305 Py_DECREF(iterator);
1306 return 0;
1307}
1308#endif /* HAVE_SIGSET_T */
1309
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001310#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001311
1312static int
Brian Curtind25aef52011-06-13 15:16:04 -05001313win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001314{
Martin Panter70214ad2016-08-04 02:38:59 +00001315 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1316 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001317 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001318
1319 if (0 == DeviceIoControl(
1320 reparse_point_handle,
1321 FSCTL_GET_REPARSE_POINT,
1322 NULL, 0, /* in buffer */
1323 target_buffer, sizeof(target_buffer),
1324 &n_bytes_returned,
1325 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001326 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001327
1328 if (reparse_tag)
1329 *reparse_tag = rdb->ReparseTag;
1330
Brian Curtind25aef52011-06-13 15:16:04 -05001331 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001332}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001333
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001334#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001335
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001336/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001337#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001338/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001339** environ directly, we must obtain it with _NSGetEnviron(). See also
1340** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001341*/
1342#include <crt_externs.h>
1343static char **environ;
1344#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001345extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001346#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001347
Barry Warsaw53699e91996-12-10 23:23:01 +00001348static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001349convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350{
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001352#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001353 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001354#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001355 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001356#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001357
Victor Stinner8c62be82010-05-06 00:08:46 +00001358 d = PyDict_New();
1359 if (d == NULL)
1360 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001361#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001362 if (environ == NULL)
1363 environ = *_NSGetEnviron();
1364#endif
1365#ifdef MS_WINDOWS
1366 /* _wenviron must be initialized in this way if the program is started
1367 through main() instead of wmain(). */
1368 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001369 e = _wenviron;
Victor Stinner8c62be82010-05-06 00:08:46 +00001370#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001371 e = environ;
1372#endif
1373 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001374 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001375 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001376 PyObject *k;
1377 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001378#ifdef MS_WINDOWS
1379 const wchar_t *p = wcschr(*e, L'=');
1380#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001381 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001382#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001383 if (p == NULL)
1384 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001385#ifdef MS_WINDOWS
1386 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1387#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001388 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001389#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001390 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001391 Py_DECREF(d);
1392 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001393 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001394#ifdef MS_WINDOWS
1395 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1396#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001397 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001398#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001399 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001401 Py_DECREF(d);
1402 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001403 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001404 if (PyDict_GetItemWithError(d, k) == NULL) {
1405 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1406 Py_DECREF(v);
1407 Py_DECREF(k);
1408 Py_DECREF(d);
1409 return NULL;
1410 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001411 }
1412 Py_DECREF(k);
1413 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001414 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001415 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001416}
1417
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001418/* Set a POSIX-specific error from errno, and return NULL */
1419
Barry Warsawd58d7641998-07-23 16:14:40 +00001420static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001421posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001422{
Victor Stinner8c62be82010-05-06 00:08:46 +00001423 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001424}
Mark Hammondef8b6542001-05-13 08:04:26 +00001425
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001426#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001427static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001428win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001429{
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 /* XXX We should pass the function name along in the future.
1431 (winreg.c also wants to pass the function name.)
1432 This would however require an additional param to the
1433 Windows error object, which is non-trivial.
1434 */
1435 errno = GetLastError();
1436 if (filename)
1437 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1438 else
1439 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001440}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001441
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001442static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001443win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001444{
1445 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001446 if (filename)
1447 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001448 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001449 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001450 filename);
1451 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001452 return PyErr_SetFromWindowsErr(err);
1453}
1454
1455static PyObject *
1456win32_error_object(const char* function, PyObject* filename)
1457{
1458 errno = GetLastError();
1459 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001460}
1461
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001462#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001463
Larry Hastings9cf065c2012-06-22 16:30:09 -07001464static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001465posix_path_object_error(PyObject *path)
1466{
1467 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1468}
1469
1470static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001471path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001472{
1473#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001474 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1475 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001476#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001477 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001478#endif
1479}
1480
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001481static PyObject *
1482path_object_error2(PyObject *path, PyObject *path2)
1483{
1484#ifdef MS_WINDOWS
1485 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1486 PyExc_OSError, 0, path, path2);
1487#else
1488 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1489#endif
1490}
1491
1492static PyObject *
1493path_error(path_t *path)
1494{
1495 return path_object_error(path->object);
1496}
Larry Hastings31826802013-10-19 00:09:25 -07001497
Larry Hastingsb0827312014-02-09 22:05:19 -08001498static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001499posix_path_error(path_t *path)
1500{
1501 return posix_path_object_error(path->object);
1502}
1503
1504static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001505path_error2(path_t *path, path_t *path2)
1506{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001507 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001508}
1509
1510
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001511/* POSIX generic methods */
1512
Larry Hastings2f936352014-08-05 14:04:04 +10001513static int
1514fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001515{
Victor Stinner8c62be82010-05-06 00:08:46 +00001516 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001517 int *pointer = (int *)p;
1518 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001519 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001520 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001521 *pointer = fd;
1522 return 1;
1523}
1524
1525static PyObject *
1526posix_fildes_fd(int fd, int (*func)(int))
1527{
1528 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001529 int async_err = 0;
1530
1531 do {
1532 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001533 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001534 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001535 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001536 Py_END_ALLOW_THREADS
1537 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1538 if (res != 0)
1539 return (!async_err) ? posix_error() : NULL;
1540 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001541}
Guido van Rossum21142a01999-01-08 21:05:37 +00001542
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001543
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001544#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001545/* This is a reimplementation of the C library's chdir function,
1546 but one that produces Win32 errors instead of DOS error codes.
1547 chdir is essentially a wrapper around SetCurrentDirectory; however,
1548 it also needs to set "magic" environment variables indicating
1549 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001550static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001551win32_wchdir(LPCWSTR path)
1552{
Victor Stinnered537822015-12-13 21:40:26 +01001553 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001554 int result;
1555 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001556
Victor Stinner8c62be82010-05-06 00:08:46 +00001557 if(!SetCurrentDirectoryW(path))
1558 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001559 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001560 if (!result)
1561 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001562 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001563 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001564 if (!new_path) {
1565 SetLastError(ERROR_OUTOFMEMORY);
1566 return FALSE;
1567 }
1568 result = GetCurrentDirectoryW(result, new_path);
1569 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001570 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001571 return FALSE;
1572 }
1573 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001574 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1575 wcsncmp(new_path, L"//", 2) == 0);
1576 if (!is_unc_like_path) {
1577 env[1] = new_path[0];
1578 result = SetEnvironmentVariableW(env, new_path);
1579 }
Victor Stinnered537822015-12-13 21:40:26 +01001580 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001581 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001582 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001583}
1584#endif
1585
Martin v. Löwis14694662006-02-03 12:54:16 +00001586#ifdef MS_WINDOWS
1587/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1588 - time stamps are restricted to second resolution
1589 - file modification times suffer from forth-and-back conversions between
1590 UTC and local time
1591 Therefore, we implement our own stat, based on the Win32 API directly.
1592*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001593#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001594#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001595
Victor Stinner6036e442015-03-08 01:58:04 +01001596static void
Steve Dowercc16be82016-09-08 10:35:16 -07001597find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1598 BY_HANDLE_FILE_INFORMATION *info,
1599 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001600{
1601 memset(info, 0, sizeof(*info));
1602 info->dwFileAttributes = pFileData->dwFileAttributes;
1603 info->ftCreationTime = pFileData->ftCreationTime;
1604 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1605 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1606 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1607 info->nFileSizeLow = pFileData->nFileSizeLow;
1608/* info->nNumberOfLinks = 1; */
1609 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1610 *reparse_tag = pFileData->dwReserved0;
1611 else
1612 *reparse_tag = 0;
1613}
1614
Guido van Rossumd8faa362007-04-27 19:54:29 +00001615static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001616attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001617{
Victor Stinner8c62be82010-05-06 00:08:46 +00001618 HANDLE hFindFile;
1619 WIN32_FIND_DATAW FileData;
1620 hFindFile = FindFirstFileW(pszFile, &FileData);
1621 if (hFindFile == INVALID_HANDLE_VALUE)
1622 return FALSE;
1623 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001624 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001625 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001626}
1627
Brian Curtind25aef52011-06-13 15:16:04 -05001628static BOOL
1629get_target_path(HANDLE hdl, wchar_t **target_path)
1630{
1631 int buf_size, result_length;
1632 wchar_t *buf;
1633
1634 /* We have a good handle to the target, use it to determine
1635 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001636 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1637 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001638 if(!buf_size)
1639 return FALSE;
1640
Victor Stinnerc36674a2016-03-16 14:30:16 +01001641 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001642 if (!buf) {
1643 SetLastError(ERROR_OUTOFMEMORY);
1644 return FALSE;
1645 }
1646
Steve Dower2ea51c92015-03-20 21:49:12 -07001647 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001648 buf, buf_size, VOLUME_NAME_DOS);
1649
1650 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001651 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001652 return FALSE;
1653 }
1654
Brian Curtind25aef52011-06-13 15:16:04 -05001655 buf[result_length] = 0;
1656
1657 *target_path = buf;
1658 return TRUE;
1659}
1660
1661static int
Steve Dowercc16be82016-09-08 10:35:16 -07001662win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001663 BOOL traverse)
1664{
Victor Stinner26de69d2011-06-17 15:15:38 +02001665 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001666 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001667 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001668 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001669 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001670 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671
Steve Dowercc16be82016-09-08 10:35:16 -07001672 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001673 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001674 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001675 0, /* share mode */
1676 NULL, /* security attributes */
1677 OPEN_EXISTING,
1678 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001679 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1680 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001681 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001682 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1683 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001684 NULL);
1685
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001686 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001687 /* Either the target doesn't exist, or we don't have access to
1688 get a handle to it. If the former, we need to return an error.
1689 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001690 DWORD lastError = GetLastError();
1691 if (lastError != ERROR_ACCESS_DENIED &&
1692 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001693 return -1;
1694 /* Could not get attributes on open file. Fall back to
1695 reading the directory. */
1696 if (!attributes_from_dir(path, &info, &reparse_tag))
1697 /* Very strange. This should not fail now */
1698 return -1;
1699 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1700 if (traverse) {
1701 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001702 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001703 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001704 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001706 } else {
1707 if (!GetFileInformationByHandle(hFile, &info)) {
1708 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001709 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001710 }
1711 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Mark Becwarb82bfac2019-02-02 16:08:23 -05001712 if (!win32_get_reparse_tag(hFile, &reparse_tag)) {
1713 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001714 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001715 }
Brian Curtind25aef52011-06-13 15:16:04 -05001716 /* Close the outer open file handle now that we're about to
1717 reopen it with different flags. */
1718 if (!CloseHandle(hFile))
1719 return -1;
1720
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001721 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001722 /* In order to call GetFinalPathNameByHandle we need to open
1723 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001724 hFile2 = CreateFileW(
1725 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1726 NULL, OPEN_EXISTING,
1727 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1728 NULL);
1729 if (hFile2 == INVALID_HANDLE_VALUE)
1730 return -1;
1731
Mark Becwarb82bfac2019-02-02 16:08:23 -05001732 if (!get_target_path(hFile2, &target_path)) {
1733 CloseHandle(hFile2);
Brian Curtind25aef52011-06-13 15:16:04 -05001734 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001735 }
1736
1737 if (!CloseHandle(hFile2)) {
1738 return -1;
1739 }
Brian Curtind25aef52011-06-13 15:16:04 -05001740
Steve Dowercc16be82016-09-08 10:35:16 -07001741 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001742 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001743 return code;
1744 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001745 } else
1746 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001747 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001748 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001749
1750 /* Set S_IEXEC if it is an .exe, .bat, ... */
1751 dot = wcsrchr(path, '.');
1752 if (dot) {
1753 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1754 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1755 result->st_mode |= 0111;
1756 }
1757 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001758}
1759
1760static int
Steve Dowercc16be82016-09-08 10:35:16 -07001761win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001762{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001763 /* Protocol violation: we explicitly clear errno, instead of
1764 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001765 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001766 errno = 0;
1767 return code;
1768}
Brian Curtind25aef52011-06-13 15:16:04 -05001769/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001770
1771 In Posix, stat automatically traverses symlinks and returns the stat
1772 structure for the target. In Windows, the equivalent GetFileAttributes by
1773 default does not traverse symlinks and instead returns attributes for
1774 the symlink.
1775
1776 Therefore, win32_lstat will get the attributes traditionally, and
1777 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001778 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001779
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001780static int
Steve Dowercc16be82016-09-08 10:35:16 -07001781win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001782{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001783 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001784}
1785
Victor Stinner8c62be82010-05-06 00:08:46 +00001786static int
Steve Dowercc16be82016-09-08 10:35:16 -07001787win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001788{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001789 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001790}
1791
Martin v. Löwis14694662006-02-03 12:54:16 +00001792#endif /* MS_WINDOWS */
1793
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001794PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001795"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001796This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001797 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001798or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1799\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001800Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1801or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001802\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001803See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001804
1805static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001806 {"st_mode", "protection bits"},
1807 {"st_ino", "inode"},
1808 {"st_dev", "device"},
1809 {"st_nlink", "number of hard links"},
1810 {"st_uid", "user ID of owner"},
1811 {"st_gid", "group ID of owner"},
1812 {"st_size", "total size, in bytes"},
1813 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1814 {NULL, "integer time of last access"},
1815 {NULL, "integer time of last modification"},
1816 {NULL, "integer time of last change"},
1817 {"st_atime", "time of last access"},
1818 {"st_mtime", "time of last modification"},
1819 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001820 {"st_atime_ns", "time of last access in nanoseconds"},
1821 {"st_mtime_ns", "time of last modification in nanoseconds"},
1822 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001823#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001824 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001825#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001826#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001828#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001829#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001830 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001831#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001832#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001833 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001834#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001835#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001836 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001837#endif
1838#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001840#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001841#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1842 {"st_file_attributes", "Windows file attribute bits"},
1843#endif
jcea6c51d512018-01-28 14:00:08 +01001844#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1845 {"st_fstype", "Type of filesystem"},
1846#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001847 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001848};
1849
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001850#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001851#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001852#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001853#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001854#endif
1855
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001856#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001857#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1858#else
1859#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1860#endif
1861
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001862#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001863#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1864#else
1865#define ST_RDEV_IDX ST_BLOCKS_IDX
1866#endif
1867
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001868#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1869#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1870#else
1871#define ST_FLAGS_IDX ST_RDEV_IDX
1872#endif
1873
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001874#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001875#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001876#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001877#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001878#endif
1879
1880#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1881#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1882#else
1883#define ST_BIRTHTIME_IDX ST_GEN_IDX
1884#endif
1885
Zachary Ware63f277b2014-06-19 09:46:37 -05001886#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1887#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1888#else
1889#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1890#endif
1891
jcea6c51d512018-01-28 14:00:08 +01001892#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1893#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1894#else
1895#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1896#endif
1897
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001898static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001899 "stat_result", /* name */
1900 stat_result__doc__, /* doc */
1901 stat_result_fields,
1902 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001903};
1904
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001905PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001906"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1907This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001908 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001909or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001910\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001911See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001912
1913static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 {"f_bsize", },
1915 {"f_frsize", },
1916 {"f_blocks", },
1917 {"f_bfree", },
1918 {"f_bavail", },
1919 {"f_files", },
1920 {"f_ffree", },
1921 {"f_favail", },
1922 {"f_flag", },
1923 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001924 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001925 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001926};
1927
1928static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 "statvfs_result", /* name */
1930 statvfs_result__doc__, /* doc */
1931 statvfs_result_fields,
1932 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001933};
1934
Ross Lagerwall7807c352011-03-17 20:20:30 +02001935#if defined(HAVE_WAITID) && !defined(__APPLE__)
1936PyDoc_STRVAR(waitid_result__doc__,
1937"waitid_result: Result from waitid.\n\n\
1938This object may be accessed either as a tuple of\n\
1939 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1940or via the attributes si_pid, si_uid, and so on.\n\
1941\n\
1942See os.waitid for more information.");
1943
1944static PyStructSequence_Field waitid_result_fields[] = {
1945 {"si_pid", },
1946 {"si_uid", },
1947 {"si_signo", },
1948 {"si_status", },
1949 {"si_code", },
1950 {0}
1951};
1952
1953static PyStructSequence_Desc waitid_result_desc = {
1954 "waitid_result", /* name */
1955 waitid_result__doc__, /* doc */
1956 waitid_result_fields,
1957 5
1958};
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001959static PyTypeObject* WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +02001960#endif
1961
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001962static int initialized;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001963static PyTypeObject* StatResultType;
1964static PyTypeObject* StatVFSResultType;
William Orr81574b82018-10-01 22:19:56 -07001965#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08001966static PyTypeObject* SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001967#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001968static newfunc structseq_new;
1969
1970static PyObject *
1971statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1972{
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 PyStructSequence *result;
1974 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001975
Victor Stinner8c62be82010-05-06 00:08:46 +00001976 result = (PyStructSequence*)structseq_new(type, args, kwds);
1977 if (!result)
1978 return NULL;
1979 /* If we have been initialized from a tuple,
1980 st_?time might be set to None. Initialize it
1981 from the int slots. */
1982 for (i = 7; i <= 9; i++) {
1983 if (result->ob_item[i+3] == Py_None) {
1984 Py_DECREF(Py_None);
1985 Py_INCREF(result->ob_item[i]);
1986 result->ob_item[i+3] = result->ob_item[i];
1987 }
1988 }
1989 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001990}
1991
1992
Larry Hastings6fe20b32012-04-19 15:07:49 -07001993static PyObject *billion = NULL;
1994
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001995static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001996fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001997{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001998 PyObject *s = _PyLong_FromTime_t(sec);
1999 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2000 PyObject *s_in_ns = NULL;
2001 PyObject *ns_total = NULL;
2002 PyObject *float_s = NULL;
2003
2004 if (!(s && ns_fractional))
2005 goto exit;
2006
2007 s_in_ns = PyNumber_Multiply(s, billion);
2008 if (!s_in_ns)
2009 goto exit;
2010
2011 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2012 if (!ns_total)
2013 goto exit;
2014
Victor Stinner01b5aab2017-10-24 02:02:00 -07002015 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2016 if (!float_s) {
2017 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002018 }
2019
2020 PyStructSequence_SET_ITEM(v, index, s);
2021 PyStructSequence_SET_ITEM(v, index+3, float_s);
2022 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2023 s = NULL;
2024 float_s = NULL;
2025 ns_total = NULL;
2026exit:
2027 Py_XDECREF(s);
2028 Py_XDECREF(ns_fractional);
2029 Py_XDECREF(s_in_ns);
2030 Py_XDECREF(ns_total);
2031 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002032}
2033
Tim Peters5aa91602002-01-30 05:46:57 +00002034/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002035 (used by posix_stat() and posix_fstat()) */
2036static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002037_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002038{
Victor Stinner8c62be82010-05-06 00:08:46 +00002039 unsigned long ansec, mnsec, cnsec;
Eddie Elizondo474eedf2018-11-13 04:09:31 -08002040 PyObject *v = PyStructSequence_New(StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 if (v == NULL)
2042 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002043
Victor Stinner8c62be82010-05-06 00:08:46 +00002044 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002045 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002046 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002047#ifdef MS_WINDOWS
2048 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002049#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002050 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002051#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002053#if defined(MS_WINDOWS)
2054 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2055 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2056#else
2057 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2058 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2059#endif
xdegaye50e86032017-05-22 11:15:08 +02002060 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2061 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002062
Martin v. Löwis14694662006-02-03 12:54:16 +00002063#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002064 ansec = st->st_atim.tv_nsec;
2065 mnsec = st->st_mtim.tv_nsec;
2066 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002067#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002068 ansec = st->st_atimespec.tv_nsec;
2069 mnsec = st->st_mtimespec.tv_nsec;
2070 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002071#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002072 ansec = st->st_atime_nsec;
2073 mnsec = st->st_mtime_nsec;
2074 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002075#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002076 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002077#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002078 fill_time(v, 7, st->st_atime, ansec);
2079 fill_time(v, 8, st->st_mtime, mnsec);
2080 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002081
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002082#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2084 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002085#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002086#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002087 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2088 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002089#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002090#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002091 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2092 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002093#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002094#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002095 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2096 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002097#endif
2098#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002099 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002100 PyObject *val;
2101 unsigned long bsec,bnsec;
2102 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002103#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002104 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002105#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002106 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002107#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002108 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002109 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2110 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002111 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002112#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002113#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002114 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2115 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002116#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002117#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2118 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2119 PyLong_FromUnsignedLong(st->st_file_attributes));
2120#endif
jcea6c51d512018-01-28 14:00:08 +01002121#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2122 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2123 PyUnicode_FromString(st->st_fstype));
2124#endif
Fred Drake699f3522000-06-29 21:12:41 +00002125
Victor Stinner8c62be82010-05-06 00:08:46 +00002126 if (PyErr_Occurred()) {
2127 Py_DECREF(v);
2128 return NULL;
2129 }
Fred Drake699f3522000-06-29 21:12:41 +00002130
Victor Stinner8c62be82010-05-06 00:08:46 +00002131 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002132}
2133
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002134/* POSIX methods */
2135
Guido van Rossum94f6f721999-01-06 18:42:14 +00002136
2137static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002138posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002139 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002140{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002141 STRUCT_STAT st;
2142 int result;
2143
2144#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2145 if (follow_symlinks_specified(function_name, follow_symlinks))
2146 return NULL;
2147#endif
2148
2149 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2150 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2151 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2152 return NULL;
2153
2154 Py_BEGIN_ALLOW_THREADS
2155 if (path->fd != -1)
2156 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002157#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002158 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002159 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002160 else
Steve Dowercc16be82016-09-08 10:35:16 -07002161 result = win32_lstat(path->wide, &st);
2162#else
2163 else
2164#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002165 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2166 result = LSTAT(path->narrow, &st);
2167 else
Steve Dowercc16be82016-09-08 10:35:16 -07002168#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002169#ifdef HAVE_FSTATAT
2170 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2171 result = fstatat(dir_fd, path->narrow, &st,
2172 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2173 else
Steve Dowercc16be82016-09-08 10:35:16 -07002174#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002175 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002176#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002177 Py_END_ALLOW_THREADS
2178
Victor Stinner292c8352012-10-30 02:17:38 +01002179 if (result != 0) {
2180 return path_error(path);
2181 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002182
2183 return _pystat_fromstructstat(&st);
2184}
2185
Larry Hastings2f936352014-08-05 14:04:04 +10002186/*[python input]
2187
2188for s in """
2189
2190FACCESSAT
2191FCHMODAT
2192FCHOWNAT
2193FSTATAT
2194LINKAT
2195MKDIRAT
2196MKFIFOAT
2197MKNODAT
2198OPENAT
2199READLINKAT
2200SYMLINKAT
2201UNLINKAT
2202
2203""".strip().split():
2204 s = s.strip()
2205 print("""
2206#ifdef HAVE_{s}
2207 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002208#else
Larry Hastings2f936352014-08-05 14:04:04 +10002209 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002210#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002211""".rstrip().format(s=s))
2212
2213for s in """
2214
2215FCHDIR
2216FCHMOD
2217FCHOWN
2218FDOPENDIR
2219FEXECVE
2220FPATHCONF
2221FSTATVFS
2222FTRUNCATE
2223
2224""".strip().split():
2225 s = s.strip()
2226 print("""
2227#ifdef HAVE_{s}
2228 #define PATH_HAVE_{s} 1
2229#else
2230 #define PATH_HAVE_{s} 0
2231#endif
2232
2233""".rstrip().format(s=s))
2234[python start generated code]*/
2235
2236#ifdef HAVE_FACCESSAT
2237 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_FCHMODAT
2243 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2244#else
2245 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2246#endif
2247
2248#ifdef HAVE_FCHOWNAT
2249 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2250#else
2251 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2252#endif
2253
2254#ifdef HAVE_FSTATAT
2255 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2256#else
2257 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2258#endif
2259
2260#ifdef HAVE_LINKAT
2261 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2262#else
2263 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2264#endif
2265
2266#ifdef HAVE_MKDIRAT
2267 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2268#else
2269 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2270#endif
2271
2272#ifdef HAVE_MKFIFOAT
2273 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2274#else
2275 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2276#endif
2277
2278#ifdef HAVE_MKNODAT
2279 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2280#else
2281 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2282#endif
2283
2284#ifdef HAVE_OPENAT
2285 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2286#else
2287 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2288#endif
2289
2290#ifdef HAVE_READLINKAT
2291 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2292#else
2293 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2294#endif
2295
2296#ifdef HAVE_SYMLINKAT
2297 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2298#else
2299 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2300#endif
2301
2302#ifdef HAVE_UNLINKAT
2303 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2304#else
2305 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2306#endif
2307
2308#ifdef HAVE_FCHDIR
2309 #define PATH_HAVE_FCHDIR 1
2310#else
2311 #define PATH_HAVE_FCHDIR 0
2312#endif
2313
2314#ifdef HAVE_FCHMOD
2315 #define PATH_HAVE_FCHMOD 1
2316#else
2317 #define PATH_HAVE_FCHMOD 0
2318#endif
2319
2320#ifdef HAVE_FCHOWN
2321 #define PATH_HAVE_FCHOWN 1
2322#else
2323 #define PATH_HAVE_FCHOWN 0
2324#endif
2325
2326#ifdef HAVE_FDOPENDIR
2327 #define PATH_HAVE_FDOPENDIR 1
2328#else
2329 #define PATH_HAVE_FDOPENDIR 0
2330#endif
2331
2332#ifdef HAVE_FEXECVE
2333 #define PATH_HAVE_FEXECVE 1
2334#else
2335 #define PATH_HAVE_FEXECVE 0
2336#endif
2337
2338#ifdef HAVE_FPATHCONF
2339 #define PATH_HAVE_FPATHCONF 1
2340#else
2341 #define PATH_HAVE_FPATHCONF 0
2342#endif
2343
2344#ifdef HAVE_FSTATVFS
2345 #define PATH_HAVE_FSTATVFS 1
2346#else
2347 #define PATH_HAVE_FSTATVFS 0
2348#endif
2349
2350#ifdef HAVE_FTRUNCATE
2351 #define PATH_HAVE_FTRUNCATE 1
2352#else
2353 #define PATH_HAVE_FTRUNCATE 0
2354#endif
2355/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002356
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002357#ifdef MS_WINDOWS
2358 #undef PATH_HAVE_FTRUNCATE
2359 #define PATH_HAVE_FTRUNCATE 1
2360#endif
Larry Hastings31826802013-10-19 00:09:25 -07002361
Larry Hastings61272b72014-01-07 12:41:53 -08002362/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002363
2364class path_t_converter(CConverter):
2365
2366 type = "path_t"
2367 impl_by_reference = True
2368 parse_by_reference = True
2369
2370 converter = 'path_converter'
2371
2372 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002373 # right now path_t doesn't support default values.
2374 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002375 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002376 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002377
Larry Hastings2f936352014-08-05 14:04:04 +10002378 if self.c_default not in (None, 'Py_None'):
2379 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002380
2381 self.nullable = nullable
2382 self.allow_fd = allow_fd
2383
Larry Hastings7726ac92014-01-31 22:03:12 -08002384 def pre_render(self):
2385 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002386 if isinstance(value, str):
2387 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002388 return str(int(bool(value)))
2389
2390 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002391 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002392 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002393 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002394 strify(self.nullable),
2395 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002396 )
2397
2398 def cleanup(self):
2399 return "path_cleanup(&" + self.name + ");\n"
2400
2401
2402class dir_fd_converter(CConverter):
2403 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002404
Larry Hastings2f936352014-08-05 14:04:04 +10002405 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002406 if self.default in (unspecified, None):
2407 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002408 if isinstance(requires, str):
2409 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2410 else:
2411 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002412
Larry Hastings2f936352014-08-05 14:04:04 +10002413class fildes_converter(CConverter):
2414 type = 'int'
2415 converter = 'fildes_converter'
2416
2417class uid_t_converter(CConverter):
2418 type = "uid_t"
2419 converter = '_Py_Uid_Converter'
2420
2421class gid_t_converter(CConverter):
2422 type = "gid_t"
2423 converter = '_Py_Gid_Converter'
2424
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002425class dev_t_converter(CConverter):
2426 type = 'dev_t'
2427 converter = '_Py_Dev_Converter'
2428
2429class dev_t_return_converter(unsigned_long_return_converter):
2430 type = 'dev_t'
2431 conversion_fn = '_PyLong_FromDev'
2432 unsigned_cast = '(dev_t)'
2433
Larry Hastings2f936352014-08-05 14:04:04 +10002434class FSConverter_converter(CConverter):
2435 type = 'PyObject *'
2436 converter = 'PyUnicode_FSConverter'
2437 def converter_init(self):
2438 if self.default is not unspecified:
2439 fail("FSConverter_converter does not support default values")
2440 self.c_default = 'NULL'
2441
2442 def cleanup(self):
2443 return "Py_XDECREF(" + self.name + ");\n"
2444
2445class pid_t_converter(CConverter):
2446 type = 'pid_t'
2447 format_unit = '" _Py_PARSE_PID "'
2448
2449class idtype_t_converter(int_converter):
2450 type = 'idtype_t'
2451
2452class id_t_converter(CConverter):
2453 type = 'id_t'
2454 format_unit = '" _Py_PARSE_PID "'
2455
Benjamin Petersonca470632016-09-06 13:47:26 -07002456class intptr_t_converter(CConverter):
2457 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002458 format_unit = '" _Py_PARSE_INTPTR "'
2459
2460class Py_off_t_converter(CConverter):
2461 type = 'Py_off_t'
2462 converter = 'Py_off_t_converter'
2463
2464class Py_off_t_return_converter(long_return_converter):
2465 type = 'Py_off_t'
2466 conversion_fn = 'PyLong_FromPy_off_t'
2467
2468class path_confname_converter(CConverter):
2469 type="int"
2470 converter="conv_path_confname"
2471
2472class confstr_confname_converter(path_confname_converter):
2473 converter='conv_confstr_confname'
2474
2475class sysconf_confname_converter(path_confname_converter):
2476 converter="conv_sysconf_confname"
2477
2478class sched_param_converter(CConverter):
2479 type = 'struct sched_param'
2480 converter = 'convert_sched_param'
2481 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002482
Larry Hastings61272b72014-01-07 12:41:53 -08002483[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002484/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002485
Larry Hastings61272b72014-01-07 12:41:53 -08002486/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002487
Larry Hastings2a727912014-01-16 11:32:01 -08002488os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002489
2490 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002491 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002492 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002493
2494 *
2495
Larry Hastings2f936352014-08-05 14:04:04 +10002496 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002497 If not None, it should be a file descriptor open to a directory,
2498 and path should be a relative string; path will then be relative to
2499 that directory.
2500
2501 follow_symlinks: bool = True
2502 If False, and the last element of the path is a symbolic link,
2503 stat will examine the symbolic link itself instead of the file
2504 the link points to.
2505
2506Perform a stat system call on the given path.
2507
2508dir_fd and follow_symlinks may not be implemented
2509 on your platform. If they are unavailable, using them will raise a
2510 NotImplementedError.
2511
2512It's an error to use dir_fd or follow_symlinks when specifying path as
2513 an open file descriptor.
2514
Larry Hastings61272b72014-01-07 12:41:53 -08002515[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002516
Larry Hastings31826802013-10-19 00:09:25 -07002517static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002518os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002519/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002520{
2521 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2522}
2523
Larry Hastings2f936352014-08-05 14:04:04 +10002524
2525/*[clinic input]
2526os.lstat
2527
2528 path : path_t
2529
2530 *
2531
2532 dir_fd : dir_fd(requires='fstatat') = None
2533
2534Perform a stat system call on the given path, without following symbolic links.
2535
2536Like stat(), but do not follow symbolic links.
2537Equivalent to stat(path, follow_symlinks=False).
2538[clinic start generated code]*/
2539
Larry Hastings2f936352014-08-05 14:04:04 +10002540static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002541os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2542/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002543{
2544 int follow_symlinks = 0;
2545 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2546}
Larry Hastings31826802013-10-19 00:09:25 -07002547
Larry Hastings2f936352014-08-05 14:04:04 +10002548
Larry Hastings61272b72014-01-07 12:41:53 -08002549/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002550os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002551
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002552 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002553 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002554
2555 mode: int
2556 Operating-system mode bitfield. Can be F_OK to test existence,
2557 or the inclusive-OR of R_OK, W_OK, and X_OK.
2558
2559 *
2560
Larry Hastings2f936352014-08-05 14:04:04 +10002561 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002562 If not None, it should be a file descriptor open to a directory,
2563 and path should be relative; path will then be relative to that
2564 directory.
2565
2566 effective_ids: bool = False
2567 If True, access will use the effective uid/gid instead of
2568 the real uid/gid.
2569
2570 follow_symlinks: bool = True
2571 If False, and the last element of the path is a symbolic link,
2572 access will examine the symbolic link itself instead of the file
2573 the link points to.
2574
2575Use the real uid/gid to test for access to a path.
2576
2577{parameters}
2578dir_fd, effective_ids, and follow_symlinks may not be implemented
2579 on your platform. If they are unavailable, using them will raise a
2580 NotImplementedError.
2581
2582Note that most operations will use the effective uid/gid, therefore this
2583 routine can be used in a suid/sgid environment to test if the invoking user
2584 has the specified access to the path.
2585
Larry Hastings61272b72014-01-07 12:41:53 -08002586[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002587
Larry Hastings2f936352014-08-05 14:04:04 +10002588static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002589os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002590 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002591/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002592{
Larry Hastings2f936352014-08-05 14:04:04 +10002593 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002594
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002595#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002596 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002597#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002598 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002599#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002600
Larry Hastings9cf065c2012-06-22 16:30:09 -07002601#ifndef HAVE_FACCESSAT
2602 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002603 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002604
2605 if (effective_ids) {
2606 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002607 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002608 }
2609#endif
2610
2611#ifdef MS_WINDOWS
2612 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002613 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002614 Py_END_ALLOW_THREADS
2615
2616 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002617 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002618 * * we didn't get a -1, and
2619 * * write access wasn't requested,
2620 * * or the file isn't read-only,
2621 * * or it's a directory.
2622 * (Directories cannot be read-only on Windows.)
2623 */
Larry Hastings2f936352014-08-05 14:04:04 +10002624 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002625 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002626 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002627 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002628#else
2629
2630 Py_BEGIN_ALLOW_THREADS
2631#ifdef HAVE_FACCESSAT
2632 if ((dir_fd != DEFAULT_DIR_FD) ||
2633 effective_ids ||
2634 !follow_symlinks) {
2635 int flags = 0;
2636 if (!follow_symlinks)
2637 flags |= AT_SYMLINK_NOFOLLOW;
2638 if (effective_ids)
2639 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002640 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641 }
2642 else
2643#endif
Larry Hastings31826802013-10-19 00:09:25 -07002644 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002645 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002646 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002647#endif
2648
Larry Hastings9cf065c2012-06-22 16:30:09 -07002649 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002650}
2651
Guido van Rossumd371ff11999-01-25 16:12:23 +00002652#ifndef F_OK
2653#define F_OK 0
2654#endif
2655#ifndef R_OK
2656#define R_OK 4
2657#endif
2658#ifndef W_OK
2659#define W_OK 2
2660#endif
2661#ifndef X_OK
2662#define X_OK 1
2663#endif
2664
Larry Hastings31826802013-10-19 00:09:25 -07002665
Guido van Rossumd371ff11999-01-25 16:12:23 +00002666#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002667/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002668os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002669
2670 fd: int
2671 Integer file descriptor handle.
2672
2673 /
2674
2675Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002676[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002677
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002678static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002679os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002680/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002681{
2682 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002683
Larry Hastings31826802013-10-19 00:09:25 -07002684 ret = ttyname(fd);
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002685 if (ret == NULL) {
2686 return posix_error();
2687 }
2688 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002689}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002690#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002691
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002692#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002693/*[clinic input]
2694os.ctermid
2695
2696Return the name of the controlling terminal for this process.
2697[clinic start generated code]*/
2698
Larry Hastings2f936352014-08-05 14:04:04 +10002699static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002700os_ctermid_impl(PyObject *module)
2701/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002702{
Victor Stinner8c62be82010-05-06 00:08:46 +00002703 char *ret;
2704 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002705
Greg Wardb48bc172000-03-01 21:51:56 +00002706#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002707 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002708#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002709 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002710#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002711 if (ret == NULL)
2712 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002713 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002714}
Larry Hastings2f936352014-08-05 14:04:04 +10002715#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002716
Larry Hastings2f936352014-08-05 14:04:04 +10002717
2718/*[clinic input]
2719os.chdir
2720
2721 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2722
2723Change the current working directory to the specified path.
2724
2725path may always be specified as a string.
2726On some platforms, path may also be specified as an open file descriptor.
2727 If this functionality is unavailable, using it raises an exception.
2728[clinic start generated code]*/
2729
Larry Hastings2f936352014-08-05 14:04:04 +10002730static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002731os_chdir_impl(PyObject *module, path_t *path)
2732/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002733{
2734 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002735
2736 Py_BEGIN_ALLOW_THREADS
2737#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002738 /* on unix, success = 0, on windows, success = !0 */
2739 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002740#else
2741#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002742 if (path->fd != -1)
2743 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002744 else
2745#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002746 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002747#endif
2748 Py_END_ALLOW_THREADS
2749
2750 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002751 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002752 }
2753
Larry Hastings2f936352014-08-05 14:04:04 +10002754 Py_RETURN_NONE;
2755}
2756
2757
2758#ifdef HAVE_FCHDIR
2759/*[clinic input]
2760os.fchdir
2761
2762 fd: fildes
2763
2764Change to the directory of the given file descriptor.
2765
2766fd must be opened on a directory, not a file.
2767Equivalent to os.chdir(fd).
2768
2769[clinic start generated code]*/
2770
Fred Drake4d1e64b2002-04-15 19:40:07 +00002771static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002772os_fchdir_impl(PyObject *module, int fd)
2773/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002774{
Larry Hastings2f936352014-08-05 14:04:04 +10002775 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002776}
2777#endif /* HAVE_FCHDIR */
2778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002779
Larry Hastings2f936352014-08-05 14:04:04 +10002780/*[clinic input]
2781os.chmod
2782
2783 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002784 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002785 On some platforms, path may also be specified as an open file descriptor.
2786 If this functionality is unavailable, using it raises an exception.
2787
2788 mode: int
2789 Operating-system mode bitfield.
2790
2791 *
2792
2793 dir_fd : dir_fd(requires='fchmodat') = None
2794 If not None, it should be a file descriptor open to a directory,
2795 and path should be relative; path will then be relative to that
2796 directory.
2797
2798 follow_symlinks: bool = True
2799 If False, and the last element of the path is a symbolic link,
2800 chmod will modify the symbolic link itself instead of the file
2801 the link points to.
2802
2803Change the access permissions of a file.
2804
2805It is an error to use dir_fd or follow_symlinks when specifying path as
2806 an open file descriptor.
2807dir_fd and follow_symlinks may not be implemented on your platform.
2808 If they are unavailable, using them will raise a NotImplementedError.
2809
2810[clinic start generated code]*/
2811
Larry Hastings2f936352014-08-05 14:04:04 +10002812static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002813os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002814 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002815/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002816{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002817 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002819#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002820 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002821#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002822
Larry Hastings9cf065c2012-06-22 16:30:09 -07002823#ifdef HAVE_FCHMODAT
2824 int fchmodat_nofollow_unsupported = 0;
2825#endif
2826
Larry Hastings9cf065c2012-06-22 16:30:09 -07002827#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2828 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002829 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002830#endif
2831
2832#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002833 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002834 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002835 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002836 result = 0;
2837 else {
2838 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002839 attr &= ~FILE_ATTRIBUTE_READONLY;
2840 else
2841 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002842 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002843 }
2844 Py_END_ALLOW_THREADS
2845
2846 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002847 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002848 }
2849#else /* MS_WINDOWS */
2850 Py_BEGIN_ALLOW_THREADS
2851#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002852 if (path->fd != -1)
2853 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002854 else
2855#endif
2856#ifdef HAVE_LCHMOD
2857 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002858 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859 else
2860#endif
2861#ifdef HAVE_FCHMODAT
2862 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2863 /*
2864 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2865 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002866 * and then says it isn't implemented yet.
2867 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002868 *
2869 * Once it is supported, os.chmod will automatically
2870 * support dir_fd and follow_symlinks=False. (Hopefully.)
2871 * Until then, we need to be careful what exception we raise.
2872 */
Larry Hastings2f936352014-08-05 14:04:04 +10002873 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002874 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2875 /*
2876 * But wait! We can't throw the exception without allowing threads,
2877 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2878 */
2879 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002880 result &&
2881 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2882 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002883 }
2884 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002885#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002886 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002887 Py_END_ALLOW_THREADS
2888
2889 if (result) {
2890#ifdef HAVE_FCHMODAT
2891 if (fchmodat_nofollow_unsupported) {
2892 if (dir_fd != DEFAULT_DIR_FD)
2893 dir_fd_and_follow_symlinks_invalid("chmod",
2894 dir_fd, follow_symlinks);
2895 else
2896 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002897 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002898 }
2899 else
2900#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002901 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002902 }
2903#endif
2904
Larry Hastings2f936352014-08-05 14:04:04 +10002905 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002906}
2907
Larry Hastings9cf065c2012-06-22 16:30:09 -07002908
Christian Heimes4e30a842007-11-30 22:12:06 +00002909#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002910/*[clinic input]
2911os.fchmod
2912
2913 fd: int
2914 mode: int
2915
2916Change the access permissions of the file given by file descriptor fd.
2917
2918Equivalent to os.chmod(fd, mode).
2919[clinic start generated code]*/
2920
Larry Hastings2f936352014-08-05 14:04:04 +10002921static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002922os_fchmod_impl(PyObject *module, int fd, int mode)
2923/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002924{
2925 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002926 int async_err = 0;
2927
2928 do {
2929 Py_BEGIN_ALLOW_THREADS
2930 res = fchmod(fd, mode);
2931 Py_END_ALLOW_THREADS
2932 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2933 if (res != 0)
2934 return (!async_err) ? posix_error() : NULL;
2935
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002937}
2938#endif /* HAVE_FCHMOD */
2939
Larry Hastings2f936352014-08-05 14:04:04 +10002940
Christian Heimes4e30a842007-11-30 22:12:06 +00002941#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002942/*[clinic input]
2943os.lchmod
2944
2945 path: path_t
2946 mode: int
2947
2948Change the access permissions of a file, without following symbolic links.
2949
2950If path is a symlink, this affects the link itself rather than the target.
2951Equivalent to chmod(path, mode, follow_symlinks=False)."
2952[clinic start generated code]*/
2953
Larry Hastings2f936352014-08-05 14:04:04 +10002954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002955os_lchmod_impl(PyObject *module, path_t *path, int mode)
2956/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002957{
Victor Stinner8c62be82010-05-06 00:08:46 +00002958 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002959 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002960 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002961 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002962 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002963 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002964 return NULL;
2965 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002966 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002967}
2968#endif /* HAVE_LCHMOD */
2969
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002970
Thomas Wouterscf297e42007-02-23 15:07:44 +00002971#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002972/*[clinic input]
2973os.chflags
2974
2975 path: path_t
2976 flags: unsigned_long(bitwise=True)
2977 follow_symlinks: bool=True
2978
2979Set file flags.
2980
2981If follow_symlinks is False, and the last element of the path is a symbolic
2982 link, chflags will change flags on the symbolic link itself instead of the
2983 file the link points to.
2984follow_symlinks may not be implemented on your platform. If it is
2985unavailable, using it will raise a NotImplementedError.
2986
2987[clinic start generated code]*/
2988
Larry Hastings2f936352014-08-05 14:04:04 +10002989static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002990os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002991 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002992/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002993{
2994 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002995
2996#ifndef HAVE_LCHFLAGS
2997 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002998 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002999#endif
3000
Victor Stinner8c62be82010-05-06 00:08:46 +00003001 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003002#ifdef HAVE_LCHFLAGS
3003 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003004 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003005 else
3006#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003007 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003008 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003009
Larry Hastings2f936352014-08-05 14:04:04 +10003010 if (result)
3011 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003012
Larry Hastings2f936352014-08-05 14:04:04 +10003013 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003014}
3015#endif /* HAVE_CHFLAGS */
3016
Larry Hastings2f936352014-08-05 14:04:04 +10003017
Thomas Wouterscf297e42007-02-23 15:07:44 +00003018#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003019/*[clinic input]
3020os.lchflags
3021
3022 path: path_t
3023 flags: unsigned_long(bitwise=True)
3024
3025Set file flags.
3026
3027This function will not follow symbolic links.
3028Equivalent to chflags(path, flags, follow_symlinks=False).
3029[clinic start generated code]*/
3030
Larry Hastings2f936352014-08-05 14:04:04 +10003031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003032os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3033/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003034{
Victor Stinner8c62be82010-05-06 00:08:46 +00003035 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003036 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003037 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003038 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003039 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003040 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003041 }
Victor Stinner292c8352012-10-30 02:17:38 +01003042 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003043}
3044#endif /* HAVE_LCHFLAGS */
3045
Larry Hastings2f936352014-08-05 14:04:04 +10003046
Martin v. Löwis244edc82001-10-04 22:44:26 +00003047#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003048/*[clinic input]
3049os.chroot
3050 path: path_t
3051
3052Change root directory to path.
3053
3054[clinic start generated code]*/
3055
Larry Hastings2f936352014-08-05 14:04:04 +10003056static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003057os_chroot_impl(PyObject *module, path_t *path)
3058/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003059{
3060 int res;
3061 Py_BEGIN_ALLOW_THREADS
3062 res = chroot(path->narrow);
3063 Py_END_ALLOW_THREADS
3064 if (res < 0)
3065 return path_error(path);
3066 Py_RETURN_NONE;
3067}
3068#endif /* HAVE_CHROOT */
3069
Martin v. Löwis244edc82001-10-04 22:44:26 +00003070
Guido van Rossum21142a01999-01-08 21:05:37 +00003071#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003072/*[clinic input]
3073os.fsync
3074
3075 fd: fildes
3076
3077Force write of fd to disk.
3078[clinic start generated code]*/
3079
Larry Hastings2f936352014-08-05 14:04:04 +10003080static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003081os_fsync_impl(PyObject *module, int fd)
3082/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003083{
3084 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003085}
3086#endif /* HAVE_FSYNC */
3087
Larry Hastings2f936352014-08-05 14:04:04 +10003088
Ross Lagerwall7807c352011-03-17 20:20:30 +02003089#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003090/*[clinic input]
3091os.sync
3092
3093Force write of everything to disk.
3094[clinic start generated code]*/
3095
Larry Hastings2f936352014-08-05 14:04:04 +10003096static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003097os_sync_impl(PyObject *module)
3098/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003099{
3100 Py_BEGIN_ALLOW_THREADS
3101 sync();
3102 Py_END_ALLOW_THREADS
3103 Py_RETURN_NONE;
3104}
Larry Hastings2f936352014-08-05 14:04:04 +10003105#endif /* HAVE_SYNC */
3106
Ross Lagerwall7807c352011-03-17 20:20:30 +02003107
Guido van Rossum21142a01999-01-08 21:05:37 +00003108#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003109#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003110extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3111#endif
3112
Larry Hastings2f936352014-08-05 14:04:04 +10003113/*[clinic input]
3114os.fdatasync
3115
3116 fd: fildes
3117
3118Force write of fd to disk without forcing update of metadata.
3119[clinic start generated code]*/
3120
Larry Hastings2f936352014-08-05 14:04:04 +10003121static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003122os_fdatasync_impl(PyObject *module, int fd)
3123/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003124{
3125 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003126}
3127#endif /* HAVE_FDATASYNC */
3128
3129
Fredrik Lundh10723342000-07-10 16:38:09 +00003130#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003131/*[clinic input]
3132os.chown
3133
3134 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003135 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003136
3137 uid: uid_t
3138
3139 gid: gid_t
3140
3141 *
3142
3143 dir_fd : dir_fd(requires='fchownat') = None
3144 If not None, it should be a file descriptor open to a directory,
3145 and path should be relative; path will then be relative to that
3146 directory.
3147
3148 follow_symlinks: bool = True
3149 If False, and the last element of the path is a symbolic link,
3150 stat will examine the symbolic link itself instead of the file
3151 the link points to.
3152
3153Change the owner and group id of path to the numeric uid and gid.\
3154
3155path may always be specified as a string.
3156On some platforms, path may also be specified as an open file descriptor.
3157 If this functionality is unavailable, using it raises an exception.
3158If dir_fd is not None, it should be a file descriptor open to a directory,
3159 and path should be relative; path will then be relative to that directory.
3160If follow_symlinks is False, and the last element of the path is a symbolic
3161 link, chown will modify the symbolic link itself instead of the file the
3162 link points to.
3163It is an error to use dir_fd or follow_symlinks when specifying path as
3164 an open file descriptor.
3165dir_fd and follow_symlinks may not be implemented on your platform.
3166 If they are unavailable, using them will raise a NotImplementedError.
3167
3168[clinic start generated code]*/
3169
Larry Hastings2f936352014-08-05 14:04:04 +10003170static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003171os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003172 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003173/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003174{
3175 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003176
3177#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3178 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003179 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003180#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003181 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3182 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3183 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003184
3185#ifdef __APPLE__
3186 /*
3187 * This is for Mac OS X 10.3, which doesn't have lchown.
3188 * (But we still have an lchown symbol because of weak-linking.)
3189 * It doesn't have fchownat either. So there's no possibility
3190 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003191 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192 if ((!follow_symlinks) && (lchown == NULL)) {
3193 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003194 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003195 }
3196#endif
3197
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003199#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003200 if (path->fd != -1)
3201 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003202 else
3203#endif
3204#ifdef HAVE_LCHOWN
3205 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003206 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003207 else
3208#endif
3209#ifdef HAVE_FCHOWNAT
3210 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003211 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003212 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3213 else
3214#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003215 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003216 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003217
Larry Hastings2f936352014-08-05 14:04:04 +10003218 if (result)
3219 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003220
Larry Hastings2f936352014-08-05 14:04:04 +10003221 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003222}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003223#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003224
Larry Hastings2f936352014-08-05 14:04:04 +10003225
Christian Heimes4e30a842007-11-30 22:12:06 +00003226#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003227/*[clinic input]
3228os.fchown
3229
3230 fd: int
3231 uid: uid_t
3232 gid: gid_t
3233
3234Change the owner and group id of the file specified by file descriptor.
3235
3236Equivalent to os.chown(fd, uid, gid).
3237
3238[clinic start generated code]*/
3239
Larry Hastings2f936352014-08-05 14:04:04 +10003240static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003241os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3242/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003243{
Victor Stinner8c62be82010-05-06 00:08:46 +00003244 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003245 int async_err = 0;
3246
3247 do {
3248 Py_BEGIN_ALLOW_THREADS
3249 res = fchown(fd, uid, gid);
3250 Py_END_ALLOW_THREADS
3251 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3252 if (res != 0)
3253 return (!async_err) ? posix_error() : NULL;
3254
Victor Stinner8c62be82010-05-06 00:08:46 +00003255 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003256}
3257#endif /* HAVE_FCHOWN */
3258
Larry Hastings2f936352014-08-05 14:04:04 +10003259
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003260#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003261/*[clinic input]
3262os.lchown
3263
3264 path : path_t
3265 uid: uid_t
3266 gid: gid_t
3267
3268Change the owner and group id of path to the numeric uid and gid.
3269
3270This function will not follow symbolic links.
3271Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3272[clinic start generated code]*/
3273
Larry Hastings2f936352014-08-05 14:04:04 +10003274static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003275os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3276/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003277{
Victor Stinner8c62be82010-05-06 00:08:46 +00003278 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003279 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003280 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003281 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003282 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003283 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003284 }
Larry Hastings2f936352014-08-05 14:04:04 +10003285 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003286}
3287#endif /* HAVE_LCHOWN */
3288
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003289
Barry Warsaw53699e91996-12-10 23:23:01 +00003290static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003291posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003292{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003293 char *buf, *tmpbuf;
3294 char *cwd;
3295 const size_t chunk = 1024;
3296 size_t buflen = 0;
3297 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003298
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003299#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003300 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003301 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003302 wchar_t *wbuf2 = wbuf;
3303 PyObject *resobj;
3304 DWORD len;
3305 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003306 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003307 /* If the buffer is large enough, len does not include the
3308 terminating \0. If the buffer is too small, len includes
3309 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003310 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003311 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003312 if (wbuf2)
3313 len = GetCurrentDirectoryW(len, wbuf2);
3314 }
3315 Py_END_ALLOW_THREADS
3316 if (!wbuf2) {
3317 PyErr_NoMemory();
3318 return NULL;
3319 }
3320 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003321 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003322 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003323 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003324 }
3325 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003326 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003327 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003328 return resobj;
3329 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003330
3331 if (win32_warn_bytes_api())
3332 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003333#endif
3334
Victor Stinner4403d7d2015-04-25 00:16:10 +02003335 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003336 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003337 do {
3338 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003339#ifdef MS_WINDOWS
3340 if (buflen > INT_MAX) {
3341 PyErr_NoMemory();
3342 break;
3343 }
3344#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003345 tmpbuf = PyMem_RawRealloc(buf, buflen);
3346 if (tmpbuf == NULL)
3347 break;
3348
3349 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003350#ifdef MS_WINDOWS
3351 cwd = getcwd(buf, (int)buflen);
3352#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003353 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003354#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003355 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003357
3358 if (cwd == NULL) {
3359 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003360 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003361 }
3362
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003364 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3365 else
3366 obj = PyUnicode_DecodeFSDefault(buf);
3367 PyMem_RawFree(buf);
3368
3369 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003370}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003371
Larry Hastings2f936352014-08-05 14:04:04 +10003372
3373/*[clinic input]
3374os.getcwd
3375
3376Return a unicode string representing the current working directory.
3377[clinic start generated code]*/
3378
Larry Hastings2f936352014-08-05 14:04:04 +10003379static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003380os_getcwd_impl(PyObject *module)
3381/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003382{
3383 return posix_getcwd(0);
3384}
3385
Larry Hastings2f936352014-08-05 14:04:04 +10003386
3387/*[clinic input]
3388os.getcwdb
3389
3390Return a bytes string representing the current working directory.
3391[clinic start generated code]*/
3392
Larry Hastings2f936352014-08-05 14:04:04 +10003393static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003394os_getcwdb_impl(PyObject *module)
3395/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003396{
3397 return posix_getcwd(1);
3398}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003399
Larry Hastings2f936352014-08-05 14:04:04 +10003400
Larry Hastings9cf065c2012-06-22 16:30:09 -07003401#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3402#define HAVE_LINK 1
3403#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003404
Guido van Rossumb6775db1994-08-01 11:34:53 +00003405#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003406/*[clinic input]
3407
3408os.link
3409
3410 src : path_t
3411 dst : path_t
3412 *
3413 src_dir_fd : dir_fd = None
3414 dst_dir_fd : dir_fd = None
3415 follow_symlinks: bool = True
3416
3417Create a hard link to a file.
3418
3419If either src_dir_fd or dst_dir_fd is not None, it should be a file
3420 descriptor open to a directory, and the respective path string (src or dst)
3421 should be relative; the path will then be relative to that directory.
3422If follow_symlinks is False, and the last element of src is a symbolic
3423 link, link will create a link to the symbolic link itself instead of the
3424 file the link points to.
3425src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3426 platform. If they are unavailable, using them will raise a
3427 NotImplementedError.
3428[clinic start generated code]*/
3429
Larry Hastings2f936352014-08-05 14:04:04 +10003430static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003431os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003432 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003433/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003434{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003435#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003436 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437#else
3438 int result;
3439#endif
3440
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441#ifndef HAVE_LINKAT
3442 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3443 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003444 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445 }
3446#endif
3447
Steve Dowercc16be82016-09-08 10:35:16 -07003448#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003449 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003450 PyErr_SetString(PyExc_NotImplementedError,
3451 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003452 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453 }
Steve Dowercc16be82016-09-08 10:35:16 -07003454#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003455
Brian Curtin1b9df392010-11-24 20:24:31 +00003456#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003458 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003459 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003460
Larry Hastings2f936352014-08-05 14:04:04 +10003461 if (!result)
3462 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463#else
3464 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003465#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003466 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3467 (dst_dir_fd != DEFAULT_DIR_FD) ||
3468 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003469 result = linkat(src_dir_fd, src->narrow,
3470 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3472 else
Steve Dowercc16be82016-09-08 10:35:16 -07003473#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003474 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003476
Larry Hastings2f936352014-08-05 14:04:04 +10003477 if (result)
3478 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003479#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480
Larry Hastings2f936352014-08-05 14:04:04 +10003481 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003482}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483#endif
3484
Brian Curtin1b9df392010-11-24 20:24:31 +00003485
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003486#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003487static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003488_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003489{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490 PyObject *v;
3491 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3492 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003493 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003494 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003495 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497
Steve Dowercc16be82016-09-08 10:35:16 -07003498 WIN32_FIND_DATAW wFileData;
3499 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003500
Steve Dowercc16be82016-09-08 10:35:16 -07003501 if (!path->wide) { /* Default arg: "." */
3502 po_wchars = L".";
3503 len = 1;
3504 } else {
3505 po_wchars = path->wide;
3506 len = wcslen(path->wide);
3507 }
3508 /* The +5 is so we can append "\\*.*\0" */
3509 wnamebuf = PyMem_New(wchar_t, len + 5);
3510 if (!wnamebuf) {
3511 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003512 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003513 }
Steve Dowercc16be82016-09-08 10:35:16 -07003514 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003515 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003516 wchar_t wch = wnamebuf[len-1];
3517 if (wch != SEP && wch != ALTSEP && wch != L':')
3518 wnamebuf[len++] = SEP;
3519 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003520 }
Steve Dowercc16be82016-09-08 10:35:16 -07003521 if ((list = PyList_New(0)) == NULL) {
3522 goto exit;
3523 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003524 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003525 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003526 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 if (hFindFile == INVALID_HANDLE_VALUE) {
3528 int error = GetLastError();
3529 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530 goto exit;
3531 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003532 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 }
3535 do {
3536 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003537 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3538 wcscmp(wFileData.cFileName, L"..") != 0) {
3539 v = PyUnicode_FromWideChar(wFileData.cFileName,
3540 wcslen(wFileData.cFileName));
3541 if (path->narrow && v) {
3542 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3543 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003545 Py_DECREF(list);
3546 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 break;
3548 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003551 Py_DECREF(list);
3552 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 break;
3554 }
3555 Py_DECREF(v);
3556 }
3557 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003558 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003559 Py_END_ALLOW_THREADS
3560 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3561 it got to the end of the directory. */
3562 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003564 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003565 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003566 }
3567 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003568
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569exit:
3570 if (hFindFile != INVALID_HANDLE_VALUE) {
3571 if (FindClose(hFindFile) == FALSE) {
3572 if (list != NULL) {
3573 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003574 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 }
3576 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003578 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003579
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003581} /* end of _listdir_windows_no_opendir */
3582
3583#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3584
3585static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003586_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003587{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003588 PyObject *v;
3589 DIR *dirp = NULL;
3590 struct dirent *ep;
3591 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003592#ifdef HAVE_FDOPENDIR
3593 int fd = -1;
3594#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003595
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003597#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003598 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003599 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003600 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003601 if (fd == -1)
3602 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003603
Larry Hastingsfdaea062012-06-25 04:42:23 -07003604 return_str = 1;
3605
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 Py_BEGIN_ALLOW_THREADS
3607 dirp = fdopendir(fd);
3608 Py_END_ALLOW_THREADS
3609 }
3610 else
3611#endif
3612 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003613 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003614 if (path->narrow) {
3615 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003616 /* only return bytes if they specified a bytes-like object */
3617 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003618 }
3619 else {
3620 name = ".";
3621 return_str = 1;
3622 }
3623
Larry Hastings9cf065c2012-06-22 16:30:09 -07003624 Py_BEGIN_ALLOW_THREADS
3625 dirp = opendir(name);
3626 Py_END_ALLOW_THREADS
3627 }
3628
3629 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003630 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003631#ifdef HAVE_FDOPENDIR
3632 if (fd != -1) {
3633 Py_BEGIN_ALLOW_THREADS
3634 close(fd);
3635 Py_END_ALLOW_THREADS
3636 }
3637#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003638 goto exit;
3639 }
3640 if ((list = PyList_New(0)) == NULL) {
3641 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003642 }
3643 for (;;) {
3644 errno = 0;
3645 Py_BEGIN_ALLOW_THREADS
3646 ep = readdir(dirp);
3647 Py_END_ALLOW_THREADS
3648 if (ep == NULL) {
3649 if (errno == 0) {
3650 break;
3651 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003652 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003653 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003654 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003655 }
3656 }
3657 if (ep->d_name[0] == '.' &&
3658 (NAMLEN(ep) == 1 ||
3659 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3660 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003661 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003662 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3663 else
3664 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003666 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003667 break;
3668 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003669 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003670 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003671 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 break;
3673 }
3674 Py_DECREF(v);
3675 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003676
Larry Hastings9cf065c2012-06-22 16:30:09 -07003677exit:
3678 if (dirp != NULL) {
3679 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003680#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 if (fd > -1)
3682 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003683#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003684 closedir(dirp);
3685 Py_END_ALLOW_THREADS
3686 }
3687
Larry Hastings9cf065c2012-06-22 16:30:09 -07003688 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003689} /* end of _posix_listdir */
3690#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003691
Larry Hastings2f936352014-08-05 14:04:04 +10003692
3693/*[clinic input]
3694os.listdir
3695
3696 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3697
3698Return a list containing the names of the files in the directory.
3699
BNMetricsb9427072018-11-02 15:20:19 +00003700path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003701 the filenames returned will also be bytes; in all other circumstances
3702 the filenames returned will be str.
3703If path is None, uses the path='.'.
3704On some platforms, path may also be specified as an open file descriptor;\
3705 the file descriptor must refer to a directory.
3706 If this functionality is unavailable, using it raises NotImplementedError.
3707
3708The list is in arbitrary order. It does not include the special
3709entries '.' and '..' even if they are present in the directory.
3710
3711
3712[clinic start generated code]*/
3713
Larry Hastings2f936352014-08-05 14:04:04 +10003714static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003715os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003716/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003717{
3718#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3719 return _listdir_windows_no_opendir(path, NULL);
3720#else
3721 return _posix_listdir(path, NULL);
3722#endif
3723}
3724
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003725#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003726/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003727/*[clinic input]
3728os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003729
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003730 path: path_t
3731 /
3732
3733[clinic start generated code]*/
3734
3735static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003736os__getfullpathname_impl(PyObject *module, path_t *path)
3737/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003738{
Steve Dowercc16be82016-09-08 10:35:16 -07003739 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3740 wchar_t *wtemp;
3741 DWORD result;
3742 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003743
Steve Dowercc16be82016-09-08 10:35:16 -07003744 result = GetFullPathNameW(path->wide,
3745 Py_ARRAY_LENGTH(woutbuf),
3746 woutbuf, &wtemp);
3747 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3748 woutbufp = PyMem_New(wchar_t, result);
3749 if (!woutbufp)
3750 return PyErr_NoMemory();
3751 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003752 }
Steve Dowercc16be82016-09-08 10:35:16 -07003753 if (result) {
3754 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3755 if (path->narrow)
3756 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3757 } else
3758 v = win32_error_object("GetFullPathNameW", path->object);
3759 if (woutbufp != woutbuf)
3760 PyMem_Free(woutbufp);
3761 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003762}
Brian Curtind40e6f72010-07-08 21:39:08 +00003763
Brian Curtind25aef52011-06-13 15:16:04 -05003764
Larry Hastings2f936352014-08-05 14:04:04 +10003765/*[clinic input]
3766os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003767
Steve Dower23ad6d02018-02-22 10:39:10 -08003768 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003769 /
3770
3771A helper function for samepath on windows.
3772[clinic start generated code]*/
3773
Larry Hastings2f936352014-08-05 14:04:04 +10003774static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003775os__getfinalpathname_impl(PyObject *module, path_t *path)
3776/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003777{
3778 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003779 wchar_t buf[MAXPATHLEN], *target_path = buf;
3780 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003781 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003782 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003783
Steve Dower23ad6d02018-02-22 10:39:10 -08003784 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003785 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08003786 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003787 0, /* desired access */
3788 0, /* share mode */
3789 NULL, /* security attributes */
3790 OPEN_EXISTING,
3791 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3792 FILE_FLAG_BACKUP_SEMANTICS,
3793 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003794 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003795
Steve Dower23ad6d02018-02-22 10:39:10 -08003796 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003797 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08003798 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003799
3800 /* We have a good handle to the target, use it to determine the
3801 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003802 while (1) {
3803 Py_BEGIN_ALLOW_THREADS
3804 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3805 buf_size, VOLUME_NAME_DOS);
3806 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003807
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003808 if (!result_length) {
3809 result = win32_error_object("GetFinalPathNameByHandleW",
3810 path->object);
3811 goto cleanup;
3812 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003813
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003814 if (result_length < buf_size) {
3815 break;
3816 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003817
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003818 wchar_t *tmp;
3819 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3820 result_length * sizeof(*tmp));
3821 if (!tmp) {
3822 result = PyErr_NoMemory();
3823 goto cleanup;
3824 }
3825
3826 buf_size = result_length;
3827 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08003828 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003829
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003830 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dower23ad6d02018-02-22 10:39:10 -08003831 if (path->narrow)
3832 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dower23ad6d02018-02-22 10:39:10 -08003833
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03003834cleanup:
3835 if (target_path != buf) {
3836 PyMem_Free(target_path);
3837 }
3838 CloseHandle(hFile);
3839 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003840}
Brian Curtin62857742010-09-06 17:07:27 +00003841
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003842/*[clinic input]
3843os._isdir
3844
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003845 path as arg: object
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003846 /
3847
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003848Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003849[clinic start generated code]*/
3850
Brian Curtin9c669cc2011-06-08 18:17:18 -05003851static PyObject *
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003852os__isdir(PyObject *module, PyObject *arg)
3853/*[clinic end generated code: output=404f334d85d4bf25 input=36cb6785874d479e]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003854{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003855 DWORD attributes;
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003856 path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0);
3857
3858 if (!path_converter(arg, &path)) {
3859 if (PyErr_ExceptionMatches(PyExc_ValueError)) {
3860 PyErr_Clear();
3861 Py_RETURN_FALSE;
3862 }
3863 return NULL;
3864 }
Brian Curtin9c669cc2011-06-08 18:17:18 -05003865
Steve Dowerb22a6772016-07-17 20:49:38 -07003866 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003867 attributes = GetFileAttributesW(path.wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003868 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003869
Serhiy Storchaka0185f342018-09-18 11:28:51 +03003870 path_cleanup(&path);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003871 if (attributes == INVALID_FILE_ATTRIBUTES)
3872 Py_RETURN_FALSE;
3873
Brian Curtin9c669cc2011-06-08 18:17:18 -05003874 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3875 Py_RETURN_TRUE;
3876 else
3877 Py_RETURN_FALSE;
3878}
Tim Golden6b528062013-08-01 12:44:00 +01003879
Tim Golden6b528062013-08-01 12:44:00 +01003880
Larry Hastings2f936352014-08-05 14:04:04 +10003881/*[clinic input]
3882os._getvolumepathname
3883
Steve Dower23ad6d02018-02-22 10:39:10 -08003884 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003885
3886A helper function for ismount on Win32.
3887[clinic start generated code]*/
3888
Larry Hastings2f936352014-08-05 14:04:04 +10003889static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08003890os__getvolumepathname_impl(PyObject *module, path_t *path)
3891/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003892{
3893 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003894 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003895 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003896 BOOL ret;
3897
Tim Golden6b528062013-08-01 12:44:00 +01003898 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08003899 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003900
Victor Stinner850a18e2017-10-24 16:53:32 -07003901 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003902 PyErr_SetString(PyExc_OverflowError, "path too long");
3903 return NULL;
3904 }
3905
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003906 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003907 if (mountpath == NULL)
3908 return PyErr_NoMemory();
3909
3910 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08003911 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003912 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003913 Py_END_ALLOW_THREADS
3914
3915 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08003916 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003917 goto exit;
3918 }
3919 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08003920 if (path->narrow)
3921 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003922
3923exit:
3924 PyMem_Free(mountpath);
3925 return result;
3926}
Tim Golden6b528062013-08-01 12:44:00 +01003927
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003928#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003929
Larry Hastings2f936352014-08-05 14:04:04 +10003930
3931/*[clinic input]
3932os.mkdir
3933
3934 path : path_t
3935
3936 mode: int = 0o777
3937
3938 *
3939
3940 dir_fd : dir_fd(requires='mkdirat') = None
3941
3942# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3943
3944Create a directory.
3945
3946If dir_fd is not None, it should be a file descriptor open to a directory,
3947 and path should be relative; path will then be relative to that directory.
3948dir_fd may not be implemented on your platform.
3949 If it is unavailable, using it will raise a NotImplementedError.
3950
3951The mode argument is ignored on Windows.
3952[clinic start generated code]*/
3953
Larry Hastings2f936352014-08-05 14:04:04 +10003954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003955os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3956/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003957{
3958 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003959
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003960#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003962 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003963 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003964
Larry Hastings2f936352014-08-05 14:04:04 +10003965 if (!result)
3966 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003967#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003968 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003969#if HAVE_MKDIRAT
3970 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003971 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003972 else
3973#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003974#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003975 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003976#else
Larry Hastings2f936352014-08-05 14:04:04 +10003977 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003978#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003979 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003980 if (result < 0)
3981 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003982#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003983 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003984}
3985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003986
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003987/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3988#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003989#include <sys/resource.h>
3990#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003991
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003992
3993#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003994/*[clinic input]
3995os.nice
3996
3997 increment: int
3998 /
3999
4000Add increment to the priority of process and return the new priority.
4001[clinic start generated code]*/
4002
Larry Hastings2f936352014-08-05 14:04:04 +10004003static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004004os_nice_impl(PyObject *module, int increment)
4005/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004006{
4007 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004008
Victor Stinner8c62be82010-05-06 00:08:46 +00004009 /* There are two flavours of 'nice': one that returns the new
4010 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004011 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004012 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004013
Victor Stinner8c62be82010-05-06 00:08:46 +00004014 If we are of the nice family that returns the new priority, we
4015 need to clear errno before the call, and check if errno is filled
4016 before calling posix_error() on a returnvalue of -1, because the
4017 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004018
Victor Stinner8c62be82010-05-06 00:08:46 +00004019 errno = 0;
4020 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004021#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004022 if (value == 0)
4023 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004024#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004025 if (value == -1 && errno != 0)
4026 /* either nice() or getpriority() returned an error */
4027 return posix_error();
4028 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004029}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004030#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004031
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004032
4033#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004034/*[clinic input]
4035os.getpriority
4036
4037 which: int
4038 who: int
4039
4040Return program scheduling priority.
4041[clinic start generated code]*/
4042
Larry Hastings2f936352014-08-05 14:04:04 +10004043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004044os_getpriority_impl(PyObject *module, int which, int who)
4045/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004046{
4047 int retval;
4048
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004049 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004050 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004051 if (errno != 0)
4052 return posix_error();
4053 return PyLong_FromLong((long)retval);
4054}
4055#endif /* HAVE_GETPRIORITY */
4056
4057
4058#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004059/*[clinic input]
4060os.setpriority
4061
4062 which: int
4063 who: int
4064 priority: int
4065
4066Set program scheduling priority.
4067[clinic start generated code]*/
4068
Larry Hastings2f936352014-08-05 14:04:04 +10004069static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004070os_setpriority_impl(PyObject *module, int which, int who, int priority)
4071/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004072{
4073 int retval;
4074
4075 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004076 if (retval == -1)
4077 return posix_error();
4078 Py_RETURN_NONE;
4079}
4080#endif /* HAVE_SETPRIORITY */
4081
4082
Barry Warsaw53699e91996-12-10 23:23:01 +00004083static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004084internal_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 +00004085{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004086 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004087 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004088
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004089#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004090 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004091 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004092#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004093 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004094#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004095
Larry Hastings9cf065c2012-06-22 16:30:09 -07004096 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4097 (dst_dir_fd != DEFAULT_DIR_FD);
4098#ifndef HAVE_RENAMEAT
4099 if (dir_fd_specified) {
4100 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004101 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004102 }
4103#endif
4104
Larry Hastings9cf065c2012-06-22 16:30:09 -07004105#ifdef MS_WINDOWS
4106 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004107 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004108 Py_END_ALLOW_THREADS
4109
Larry Hastings2f936352014-08-05 14:04:04 +10004110 if (!result)
4111 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004112
4113#else
Steve Dowercc16be82016-09-08 10:35:16 -07004114 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4115 PyErr_Format(PyExc_ValueError,
4116 "%s: src and dst must be the same type", function_name);
4117 return NULL;
4118 }
4119
Larry Hastings9cf065c2012-06-22 16:30:09 -07004120 Py_BEGIN_ALLOW_THREADS
4121#ifdef HAVE_RENAMEAT
4122 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004123 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004124 else
4125#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004126 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127 Py_END_ALLOW_THREADS
4128
Larry Hastings2f936352014-08-05 14:04:04 +10004129 if (result)
4130 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004131#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004132 Py_RETURN_NONE;
4133}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134
Larry Hastings2f936352014-08-05 14:04:04 +10004135
4136/*[clinic input]
4137os.rename
4138
4139 src : path_t
4140 dst : path_t
4141 *
4142 src_dir_fd : dir_fd = None
4143 dst_dir_fd : dir_fd = None
4144
4145Rename a file or directory.
4146
4147If either src_dir_fd or dst_dir_fd is not None, it should be a file
4148 descriptor open to a directory, and the respective path string (src or dst)
4149 should be relative; the path will then be relative to that directory.
4150src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4151 If they are unavailable, using them will raise a NotImplementedError.
4152[clinic start generated code]*/
4153
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004154static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004155os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004156 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004157/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004158{
Larry Hastings2f936352014-08-05 14:04:04 +10004159 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004160}
4161
Larry Hastings2f936352014-08-05 14:04:04 +10004162
4163/*[clinic input]
4164os.replace = os.rename
4165
4166Rename a file or directory, overwriting the destination.
4167
4168If either src_dir_fd or dst_dir_fd is not None, it should be a file
4169 descriptor open to a directory, and the respective path string (src or dst)
4170 should be relative; the path will then be relative to that directory.
4171src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004172 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004173[clinic start generated code]*/
4174
Larry Hastings2f936352014-08-05 14:04:04 +10004175static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004176os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4177 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004178/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004179{
4180 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4181}
4182
4183
4184/*[clinic input]
4185os.rmdir
4186
4187 path: path_t
4188 *
4189 dir_fd: dir_fd(requires='unlinkat') = None
4190
4191Remove a directory.
4192
4193If dir_fd is not None, it should be a file descriptor open to a directory,
4194 and path should be relative; path will then be relative to that directory.
4195dir_fd may not be implemented on your platform.
4196 If it is unavailable, using it will raise a NotImplementedError.
4197[clinic start generated code]*/
4198
Larry Hastings2f936352014-08-05 14:04:04 +10004199static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004200os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4201/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004202{
4203 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004204
4205 Py_BEGIN_ALLOW_THREADS
4206#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004207 /* Windows, success=1, UNIX, success=0 */
4208 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004209#else
4210#ifdef HAVE_UNLINKAT
4211 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004212 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004213 else
4214#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004215 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004216#endif
4217 Py_END_ALLOW_THREADS
4218
Larry Hastings2f936352014-08-05 14:04:04 +10004219 if (result)
4220 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004221
Larry Hastings2f936352014-08-05 14:04:04 +10004222 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004223}
4224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004225
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004226#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004227#ifdef MS_WINDOWS
4228/*[clinic input]
4229os.system -> long
4230
4231 command: Py_UNICODE
4232
4233Execute the command in a subshell.
4234[clinic start generated code]*/
4235
Larry Hastings2f936352014-08-05 14:04:04 +10004236static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004237os_system_impl(PyObject *module, const Py_UNICODE *command)
4238/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004239{
4240 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004241 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004242 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004243 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004244 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004245 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004246 return result;
4247}
4248#else /* MS_WINDOWS */
4249/*[clinic input]
4250os.system -> long
4251
4252 command: FSConverter
4253
4254Execute the command in a subshell.
4255[clinic start generated code]*/
4256
Larry Hastings2f936352014-08-05 14:04:04 +10004257static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004258os_system_impl(PyObject *module, PyObject *command)
4259/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004260{
4261 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004262 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004263 Py_BEGIN_ALLOW_THREADS
4264 result = system(bytes);
4265 Py_END_ALLOW_THREADS
4266 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004267}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004268#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004269#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004270
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004271
Larry Hastings2f936352014-08-05 14:04:04 +10004272/*[clinic input]
4273os.umask
4274
4275 mask: int
4276 /
4277
4278Set the current numeric umask and return the previous umask.
4279[clinic start generated code]*/
4280
Larry Hastings2f936352014-08-05 14:04:04 +10004281static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004282os_umask_impl(PyObject *module, int mask)
4283/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004284{
4285 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004286 if (i < 0)
4287 return posix_error();
4288 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004289}
4290
Brian Curtind40e6f72010-07-08 21:39:08 +00004291#ifdef MS_WINDOWS
4292
4293/* override the default DeleteFileW behavior so that directory
4294symlinks can be removed with this function, the same as with
4295Unix symlinks */
4296BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4297{
4298 WIN32_FILE_ATTRIBUTE_DATA info;
4299 WIN32_FIND_DATAW find_data;
4300 HANDLE find_data_handle;
4301 int is_directory = 0;
4302 int is_link = 0;
4303
4304 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4305 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004306
Brian Curtind40e6f72010-07-08 21:39:08 +00004307 /* Get WIN32_FIND_DATA structure for the path to determine if
4308 it is a symlink */
4309 if(is_directory &&
4310 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4311 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4312
4313 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004314 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4315 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4316 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4317 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004318 FindClose(find_data_handle);
4319 }
4320 }
4321 }
4322
4323 if (is_directory && is_link)
4324 return RemoveDirectoryW(lpFileName);
4325
4326 return DeleteFileW(lpFileName);
4327}
4328#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004329
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004330
Larry Hastings2f936352014-08-05 14:04:04 +10004331/*[clinic input]
4332os.unlink
4333
4334 path: path_t
4335 *
4336 dir_fd: dir_fd(requires='unlinkat')=None
4337
4338Remove a file (same as remove()).
4339
4340If dir_fd is not None, it should be a file descriptor open to a directory,
4341 and path should be relative; path will then be relative to that directory.
4342dir_fd may not be implemented on your platform.
4343 If it is unavailable, using it will raise a NotImplementedError.
4344
4345[clinic start generated code]*/
4346
Larry Hastings2f936352014-08-05 14:04:04 +10004347static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004348os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4349/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004350{
4351 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004352
4353 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004354 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004355#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004356 /* Windows, success=1, UNIX, success=0 */
4357 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004358#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004359#ifdef HAVE_UNLINKAT
4360 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004361 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004362 else
4363#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004364 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004365#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004366 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004367 Py_END_ALLOW_THREADS
4368
Larry Hastings2f936352014-08-05 14:04:04 +10004369 if (result)
4370 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004371
Larry Hastings2f936352014-08-05 14:04:04 +10004372 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004373}
4374
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004375
Larry Hastings2f936352014-08-05 14:04:04 +10004376/*[clinic input]
4377os.remove = os.unlink
4378
4379Remove a file (same as unlink()).
4380
4381If dir_fd is not None, it should be a file descriptor open to a directory,
4382 and path should be relative; path will then be relative to that directory.
4383dir_fd may not be implemented on your platform.
4384 If it is unavailable, using it will raise a NotImplementedError.
4385[clinic start generated code]*/
4386
Larry Hastings2f936352014-08-05 14:04:04 +10004387static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004388os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4389/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004390{
4391 return os_unlink_impl(module, path, dir_fd);
4392}
4393
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004394
Larry Hastings605a62d2012-06-24 04:33:36 -07004395static PyStructSequence_Field uname_result_fields[] = {
4396 {"sysname", "operating system name"},
4397 {"nodename", "name of machine on network (implementation-defined)"},
4398 {"release", "operating system release"},
4399 {"version", "operating system version"},
4400 {"machine", "hardware identifier"},
4401 {NULL}
4402};
4403
4404PyDoc_STRVAR(uname_result__doc__,
4405"uname_result: Result from os.uname().\n\n\
4406This object may be accessed either as a tuple of\n\
4407 (sysname, nodename, release, version, machine),\n\
4408or via the attributes sysname, nodename, release, version, and machine.\n\
4409\n\
4410See os.uname for more information.");
4411
4412static PyStructSequence_Desc uname_result_desc = {
4413 "uname_result", /* name */
4414 uname_result__doc__, /* doc */
4415 uname_result_fields,
4416 5
4417};
4418
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004419static PyTypeObject* UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07004420
4421
4422#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004423/*[clinic input]
4424os.uname
4425
4426Return an object identifying the current operating system.
4427
4428The object behaves like a named tuple with the following fields:
4429 (sysname, nodename, release, version, machine)
4430
4431[clinic start generated code]*/
4432
Larry Hastings2f936352014-08-05 14:04:04 +10004433static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004434os_uname_impl(PyObject *module)
4435/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004436{
Victor Stinner8c62be82010-05-06 00:08:46 +00004437 struct utsname u;
4438 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004439 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004440
Victor Stinner8c62be82010-05-06 00:08:46 +00004441 Py_BEGIN_ALLOW_THREADS
4442 res = uname(&u);
4443 Py_END_ALLOW_THREADS
4444 if (res < 0)
4445 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004446
Eddie Elizondo474eedf2018-11-13 04:09:31 -08004447 value = PyStructSequence_New(UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004448 if (value == NULL)
4449 return NULL;
4450
4451#define SET(i, field) \
4452 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004453 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004454 if (!o) { \
4455 Py_DECREF(value); \
4456 return NULL; \
4457 } \
4458 PyStructSequence_SET_ITEM(value, i, o); \
4459 } \
4460
4461 SET(0, u.sysname);
4462 SET(1, u.nodename);
4463 SET(2, u.release);
4464 SET(3, u.version);
4465 SET(4, u.machine);
4466
4467#undef SET
4468
4469 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004470}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004471#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004472
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004473
Larry Hastings9cf065c2012-06-22 16:30:09 -07004474
4475typedef struct {
4476 int now;
4477 time_t atime_s;
4478 long atime_ns;
4479 time_t mtime_s;
4480 long mtime_ns;
4481} utime_t;
4482
4483/*
Victor Stinner484df002014-10-09 13:52:31 +02004484 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004485 * they also intentionally leak the declaration of a pointer named "time"
4486 */
4487#define UTIME_TO_TIMESPEC \
4488 struct timespec ts[2]; \
4489 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004490 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004491 time = NULL; \
4492 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004493 ts[0].tv_sec = ut->atime_s; \
4494 ts[0].tv_nsec = ut->atime_ns; \
4495 ts[1].tv_sec = ut->mtime_s; \
4496 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004497 time = ts; \
4498 } \
4499
4500#define UTIME_TO_TIMEVAL \
4501 struct timeval tv[2]; \
4502 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004503 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004504 time = NULL; \
4505 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004506 tv[0].tv_sec = ut->atime_s; \
4507 tv[0].tv_usec = ut->atime_ns / 1000; \
4508 tv[1].tv_sec = ut->mtime_s; \
4509 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004510 time = tv; \
4511 } \
4512
4513#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004514 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004515 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004516 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004517 time = NULL; \
4518 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004519 u.actime = ut->atime_s; \
4520 u.modtime = ut->mtime_s; \
4521 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004522 }
4523
4524#define UTIME_TO_TIME_T \
4525 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004526 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004527 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004528 time = NULL; \
4529 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004530 timet[0] = ut->atime_s; \
4531 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004532 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004533 } \
4534
4535
Victor Stinner528a9ab2015-09-03 21:30:26 +02004536#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004537
4538static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004539utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004540{
4541#ifdef HAVE_UTIMENSAT
4542 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4543 UTIME_TO_TIMESPEC;
4544 return utimensat(dir_fd, path, time, flags);
4545#elif defined(HAVE_FUTIMESAT)
4546 UTIME_TO_TIMEVAL;
4547 /*
4548 * follow_symlinks will never be false here;
4549 * we only allow !follow_symlinks and dir_fd together
4550 * if we have utimensat()
4551 */
4552 assert(follow_symlinks);
4553 return futimesat(dir_fd, path, time);
4554#endif
4555}
4556
Larry Hastings2f936352014-08-05 14:04:04 +10004557 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4558#else
4559 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560#endif
4561
Victor Stinner528a9ab2015-09-03 21:30:26 +02004562#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004563
4564static int
Victor Stinner484df002014-10-09 13:52:31 +02004565utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004566{
4567#ifdef HAVE_FUTIMENS
4568 UTIME_TO_TIMESPEC;
4569 return futimens(fd, time);
4570#else
4571 UTIME_TO_TIMEVAL;
4572 return futimes(fd, time);
4573#endif
4574}
4575
Larry Hastings2f936352014-08-05 14:04:04 +10004576 #define PATH_UTIME_HAVE_FD 1
4577#else
4578 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004579#endif
4580
Victor Stinner5ebae872015-09-22 01:29:33 +02004581#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4582# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4583#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584
Victor Stinner4552ced2015-09-21 22:37:15 +02004585#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586
4587static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004588utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004589{
4590#ifdef HAVE_UTIMENSAT
4591 UTIME_TO_TIMESPEC;
4592 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4593#else
4594 UTIME_TO_TIMEVAL;
4595 return lutimes(path, time);
4596#endif
4597}
4598
4599#endif
4600
4601#ifndef MS_WINDOWS
4602
4603static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004604utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004605{
4606#ifdef HAVE_UTIMENSAT
4607 UTIME_TO_TIMESPEC;
4608 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4609#elif defined(HAVE_UTIMES)
4610 UTIME_TO_TIMEVAL;
4611 return utimes(path, time);
4612#elif defined(HAVE_UTIME_H)
4613 UTIME_TO_UTIMBUF;
4614 return utime(path, time);
4615#else
4616 UTIME_TO_TIME_T;
4617 return utime(path, time);
4618#endif
4619}
4620
4621#endif
4622
Larry Hastings76ad59b2012-05-03 00:30:07 -07004623static int
4624split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4625{
4626 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004627 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004628 divmod = PyNumber_Divmod(py_long, billion);
4629 if (!divmod)
4630 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004631 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4632 PyErr_Format(PyExc_TypeError,
4633 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4634 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4635 goto exit;
4636 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004637 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4638 if ((*s == -1) && PyErr_Occurred())
4639 goto exit;
4640 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004641 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004642 goto exit;
4643
4644 result = 1;
4645exit:
4646 Py_XDECREF(divmod);
4647 return result;
4648}
4649
Larry Hastings2f936352014-08-05 14:04:04 +10004650
4651/*[clinic input]
4652os.utime
4653
4654 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4655 times: object = NULL
4656 *
4657 ns: object = NULL
4658 dir_fd: dir_fd(requires='futimensat') = None
4659 follow_symlinks: bool=True
4660
Martin Panter0ff89092015-09-09 01:56:53 +00004661# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004662
4663Set the access and modified time of path.
4664
4665path may always be specified as a string.
4666On some platforms, path may also be specified as an open file descriptor.
4667 If this functionality is unavailable, using it raises an exception.
4668
4669If times is not None, it must be a tuple (atime, mtime);
4670 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004671If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004672 atime_ns and mtime_ns should be expressed as integer nanoseconds
4673 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004674If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004675Specifying tuples for both times and ns is an error.
4676
4677If dir_fd is not None, it should be a file descriptor open to a directory,
4678 and path should be relative; path will then be relative to that directory.
4679If follow_symlinks is False, and the last element of the path is a symbolic
4680 link, utime will modify the symbolic link itself instead of the file the
4681 link points to.
4682It is an error to use dir_fd or follow_symlinks when specifying path
4683 as an open file descriptor.
4684dir_fd and follow_symlinks may not be available on your platform.
4685 If they are unavailable, using them will raise a NotImplementedError.
4686
4687[clinic start generated code]*/
4688
Larry Hastings2f936352014-08-05 14:04:04 +10004689static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004690os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4691 int dir_fd, int follow_symlinks)
4692/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004693{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004694#ifdef MS_WINDOWS
4695 HANDLE hFile;
4696 FILETIME atime, mtime;
4697#else
4698 int result;
4699#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004700
Larry Hastings2f936352014-08-05 14:04:04 +10004701 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004702
Christian Heimesb3c87242013-08-01 00:08:16 +02004703 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004704
Larry Hastings9cf065c2012-06-22 16:30:09 -07004705 if (times && (times != Py_None) && ns) {
4706 PyErr_SetString(PyExc_ValueError,
4707 "utime: you may specify either 'times'"
4708 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004709 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004710 }
4711
4712 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004713 time_t a_sec, m_sec;
4714 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004715 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004716 PyErr_SetString(PyExc_TypeError,
4717 "utime: 'times' must be either"
4718 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004719 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004720 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004721 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004722 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004723 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004724 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004725 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004726 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004727 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004728 utime.atime_s = a_sec;
4729 utime.atime_ns = a_nsec;
4730 utime.mtime_s = m_sec;
4731 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004732 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004733 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004734 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004735 PyErr_SetString(PyExc_TypeError,
4736 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004737 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004738 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004739 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004740 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004741 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004742 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004743 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004744 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004745 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004746 }
4747 else {
4748 /* times and ns are both None/unspecified. use "now". */
4749 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004750 }
4751
Victor Stinner4552ced2015-09-21 22:37:15 +02004752#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004754 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004756
Larry Hastings2f936352014-08-05 14:04:04 +10004757 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4758 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4759 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004760 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004761
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762#if !defined(HAVE_UTIMENSAT)
4763 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004764 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 "utime: cannot use dir_fd and follow_symlinks "
4766 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004767 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004768 }
4769#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004770
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004771#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004772 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004773 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4774 NULL, OPEN_EXISTING,
4775 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004776 Py_END_ALLOW_THREADS
4777 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004778 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004779 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004780 }
4781
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004783 GetSystemTimeAsFileTime(&mtime);
4784 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004785 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004786 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004787 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4788 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004789 }
4790 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4791 /* Avoid putting the file name into the error here,
4792 as that may confuse the user into believing that
4793 something is wrong with the file, when it also
4794 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004795 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004796 CloseHandle(hFile);
4797 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004798 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004799 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004800#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004802
Victor Stinner4552ced2015-09-21 22:37:15 +02004803#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004805 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004806 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004807#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004808
Victor Stinner528a9ab2015-09-03 21:30:26 +02004809#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004810 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004811 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004812 else
4813#endif
4814
Victor Stinner528a9ab2015-09-03 21:30:26 +02004815#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004816 if (path->fd != -1)
4817 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004818 else
4819#endif
4820
Larry Hastings2f936352014-08-05 14:04:04 +10004821 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004822
4823 Py_END_ALLOW_THREADS
4824
4825 if (result < 0) {
4826 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004827 posix_error();
4828 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004829 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004830
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004831#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004832
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004833 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004834}
4835
Guido van Rossum3b066191991-06-04 19:40:25 +00004836/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004837
Larry Hastings2f936352014-08-05 14:04:04 +10004838
4839/*[clinic input]
4840os._exit
4841
4842 status: int
4843
4844Exit to the system with specified status, without normal exit processing.
4845[clinic start generated code]*/
4846
Larry Hastings2f936352014-08-05 14:04:04 +10004847static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004848os__exit_impl(PyObject *module, int status)
4849/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004850{
4851 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004852 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004853}
4854
Steve Dowercc16be82016-09-08 10:35:16 -07004855#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4856#define EXECV_CHAR wchar_t
4857#else
4858#define EXECV_CHAR char
4859#endif
4860
Martin v. Löwis114619e2002-10-07 06:44:21 +00004861#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4862static void
Steve Dowercc16be82016-09-08 10:35:16 -07004863free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004864{
Victor Stinner8c62be82010-05-06 00:08:46 +00004865 Py_ssize_t i;
4866 for (i = 0; i < count; i++)
4867 PyMem_Free(array[i]);
4868 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004869}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004870
Berker Peksag81816462016-09-15 20:19:47 +03004871static int
4872fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004873{
Victor Stinner8c62be82010-05-06 00:08:46 +00004874 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004875 PyObject *ub;
4876 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004877#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004878 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004879 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004880 *out = PyUnicode_AsWideCharString(ub, &size);
4881 if (*out)
4882 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004883#else
Berker Peksag81816462016-09-15 20:19:47 +03004884 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004885 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004886 size = PyBytes_GET_SIZE(ub);
4887 *out = PyMem_Malloc(size + 1);
4888 if (*out) {
4889 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4890 result = 1;
4891 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004892 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004893#endif
Berker Peksag81816462016-09-15 20:19:47 +03004894 Py_DECREF(ub);
4895 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004896}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004897#endif
4898
Ross Lagerwall7807c352011-03-17 20:20:30 +02004899#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004900static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004901parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4902{
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 Py_ssize_t i, pos, envc;
4904 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004905 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004906 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004907
Victor Stinner8c62be82010-05-06 00:08:46 +00004908 i = PyMapping_Size(env);
4909 if (i < 0)
4910 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004911 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004912 if (envlist == NULL) {
4913 PyErr_NoMemory();
4914 return NULL;
4915 }
4916 envc = 0;
4917 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004918 if (!keys)
4919 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004920 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004921 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004922 goto error;
4923 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4924 PyErr_Format(PyExc_TypeError,
4925 "env.keys() or env.values() is not a list");
4926 goto error;
4927 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004928
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 for (pos = 0; pos < i; pos++) {
4930 key = PyList_GetItem(keys, pos);
4931 val = PyList_GetItem(vals, pos);
4932 if (!key || !val)
4933 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004934
Berker Peksag81816462016-09-15 20:19:47 +03004935#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4936 if (!PyUnicode_FSDecoder(key, &key2))
4937 goto error;
4938 if (!PyUnicode_FSDecoder(val, &val2)) {
4939 Py_DECREF(key2);
4940 goto error;
4941 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004942 /* Search from index 1 because on Windows starting '=' is allowed for
4943 defining hidden environment variables. */
4944 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4945 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4946 {
4947 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004948 Py_DECREF(key2);
4949 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004950 goto error;
4951 }
Berker Peksag81816462016-09-15 20:19:47 +03004952 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4953#else
4954 if (!PyUnicode_FSConverter(key, &key2))
4955 goto error;
4956 if (!PyUnicode_FSConverter(val, &val2)) {
4957 Py_DECREF(key2);
4958 goto error;
4959 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004960 if (PyBytes_GET_SIZE(key2) == 0 ||
4961 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4962 {
4963 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004964 Py_DECREF(key2);
4965 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004966 goto error;
4967 }
Berker Peksag81816462016-09-15 20:19:47 +03004968 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4969 PyBytes_AS_STRING(val2));
4970#endif
4971 Py_DECREF(key2);
4972 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004973 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004974 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004975
4976 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4977 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004978 goto error;
4979 }
Berker Peksag81816462016-09-15 20:19:47 +03004980
Steve Dowercc16be82016-09-08 10:35:16 -07004981 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 }
4983 Py_DECREF(vals);
4984 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004985
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 envlist[envc] = 0;
4987 *envc_ptr = envc;
4988 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004989
4990error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004991 Py_XDECREF(keys);
4992 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004993 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004994 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004995}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004996
Steve Dowercc16be82016-09-08 10:35:16 -07004997static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004998parse_arglist(PyObject* argv, Py_ssize_t *argc)
4999{
5000 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005001 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005002 if (argvlist == NULL) {
5003 PyErr_NoMemory();
5004 return NULL;
5005 }
5006 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005007 PyObject* item = PySequence_ITEM(argv, i);
5008 if (item == NULL)
5009 goto fail;
5010 if (!fsconvert_strdup(item, &argvlist[i])) {
5011 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005012 goto fail;
5013 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005014 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005015 }
5016 argvlist[*argc] = NULL;
5017 return argvlist;
5018fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005019 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005020 free_string_array(argvlist, *argc);
5021 return NULL;
5022}
Steve Dowercc16be82016-09-08 10:35:16 -07005023
Ross Lagerwall7807c352011-03-17 20:20:30 +02005024#endif
5025
Larry Hastings2f936352014-08-05 14:04:04 +10005026
Ross Lagerwall7807c352011-03-17 20:20:30 +02005027#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005028/*[clinic input]
5029os.execv
5030
Steve Dowercc16be82016-09-08 10:35:16 -07005031 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005032 Path of executable file.
5033 argv: object
5034 Tuple or list of strings.
5035 /
5036
5037Execute an executable path with arguments, replacing current process.
5038[clinic start generated code]*/
5039
Larry Hastings2f936352014-08-05 14:04:04 +10005040static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005041os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5042/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005043{
Steve Dowercc16be82016-09-08 10:35:16 -07005044 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005045 Py_ssize_t argc;
5046
5047 /* execv has two arguments: (path, argv), where
5048 argv is a list or tuple of strings. */
5049
Ross Lagerwall7807c352011-03-17 20:20:30 +02005050 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5051 PyErr_SetString(PyExc_TypeError,
5052 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053 return NULL;
5054 }
5055 argc = PySequence_Size(argv);
5056 if (argc < 1) {
5057 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005058 return NULL;
5059 }
5060
5061 argvlist = parse_arglist(argv, &argc);
5062 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005063 return NULL;
5064 }
Steve Dowerbce26262016-11-19 19:17:26 -08005065 if (!argvlist[0][0]) {
5066 PyErr_SetString(PyExc_ValueError,
5067 "execv() arg 2 first element cannot be empty");
5068 free_string_array(argvlist, argc);
5069 return NULL;
5070 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005071
Steve Dowerbce26262016-11-19 19:17:26 -08005072 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005073#ifdef HAVE_WEXECV
5074 _wexecv(path->wide, argvlist);
5075#else
5076 execv(path->narrow, argvlist);
5077#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005078 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005079
5080 /* If we get here it's definitely an error */
5081
5082 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005083 return posix_error();
5084}
5085
Larry Hastings2f936352014-08-05 14:04:04 +10005086
5087/*[clinic input]
5088os.execve
5089
5090 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5091 Path of executable file.
5092 argv: object
5093 Tuple or list of strings.
5094 env: object
5095 Dictionary of strings mapping to strings.
5096
5097Execute an executable path with arguments, replacing current process.
5098[clinic start generated code]*/
5099
Larry Hastings2f936352014-08-05 14:04:04 +10005100static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005101os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5102/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005103{
Steve Dowercc16be82016-09-08 10:35:16 -07005104 EXECV_CHAR **argvlist = NULL;
5105 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005106 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005107
Victor Stinner8c62be82010-05-06 00:08:46 +00005108 /* execve has three arguments: (path, argv, env), where
5109 argv is a list or tuple of strings and env is a dictionary
5110 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005111
Ross Lagerwall7807c352011-03-17 20:20:30 +02005112 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005113 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005114 "execve: argv must be a tuple or list");
5115 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005116 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005117 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005118 if (argc < 1) {
5119 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5120 return NULL;
5121 }
5122
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 if (!PyMapping_Check(env)) {
5124 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005125 "execve: environment must be a mapping object");
5126 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005127 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005128
Ross Lagerwall7807c352011-03-17 20:20:30 +02005129 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005131 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005132 }
Steve Dowerbce26262016-11-19 19:17:26 -08005133 if (!argvlist[0][0]) {
5134 PyErr_SetString(PyExc_ValueError,
5135 "execve: argv first element cannot be empty");
5136 goto fail;
5137 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005138
Victor Stinner8c62be82010-05-06 00:08:46 +00005139 envlist = parse_envlist(env, &envc);
5140 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005141 goto fail;
5142
Steve Dowerbce26262016-11-19 19:17:26 -08005143 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005144#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005145 if (path->fd > -1)
5146 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005147 else
5148#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005149#ifdef HAVE_WEXECV
5150 _wexecve(path->wide, argvlist, envlist);
5151#else
Larry Hastings2f936352014-08-05 14:04:04 +10005152 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005153#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005154 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005155
5156 /* If we get here it's definitely an error */
5157
Alexey Izbyshev83460312018-10-20 03:28:22 +03005158 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005159
Steve Dowercc16be82016-09-08 10:35:16 -07005160 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005161 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005162 if (argvlist)
5163 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005164 return NULL;
5165}
Steve Dowercc16be82016-09-08 10:35:16 -07005166
Larry Hastings9cf065c2012-06-22 16:30:09 -07005167#endif /* HAVE_EXECV */
5168
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005169#ifdef HAVE_POSIX_SPAWN
5170
5171enum posix_spawn_file_actions_identifier {
5172 POSIX_SPAWN_OPEN,
5173 POSIX_SPAWN_CLOSE,
5174 POSIX_SPAWN_DUP2
5175};
5176
William Orr81574b82018-10-01 22:19:56 -07005177#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005178static int
Pablo Galindo254a4662018-09-07 16:44:24 +01005179convert_sched_param(PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005180#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005181
5182static int
Victor Stinner325e4ba2019-02-01 15:47:24 +01005183parse_posix_spawn_flags(const char *func_name, PyObject *setpgroup,
5184 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005185 PyObject *setsigdef, PyObject *scheduler,
5186 posix_spawnattr_t *attrp)
5187{
5188 long all_flags = 0;
5189
5190 errno = posix_spawnattr_init(attrp);
5191 if (errno) {
5192 posix_error();
5193 return -1;
5194 }
5195
5196 if (setpgroup) {
5197 pid_t pgid = PyLong_AsPid(setpgroup);
5198 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5199 goto fail;
5200 }
5201 errno = posix_spawnattr_setpgroup(attrp, pgid);
5202 if (errno) {
5203 posix_error();
5204 goto fail;
5205 }
5206 all_flags |= POSIX_SPAWN_SETPGROUP;
5207 }
5208
5209 if (resetids) {
5210 all_flags |= POSIX_SPAWN_RESETIDS;
5211 }
5212
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005213 if (setsid) {
5214#ifdef POSIX_SPAWN_SETSID
5215 all_flags |= POSIX_SPAWN_SETSID;
5216#elif defined(POSIX_SPAWN_SETSID_NP)
5217 all_flags |= POSIX_SPAWN_SETSID_NP;
5218#else
5219 argument_unavailable_error(func_name, "setsid");
5220 return -1;
5221#endif
5222 }
5223
Pablo Galindo254a4662018-09-07 16:44:24 +01005224 if (setsigmask) {
5225 sigset_t set;
5226 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5227 goto fail;
5228 }
5229 errno = posix_spawnattr_setsigmask(attrp, &set);
5230 if (errno) {
5231 posix_error();
5232 goto fail;
5233 }
5234 all_flags |= POSIX_SPAWN_SETSIGMASK;
5235 }
5236
5237 if (setsigdef) {
5238 sigset_t set;
5239 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5240 goto fail;
5241 }
5242 errno = posix_spawnattr_setsigdefault(attrp, &set);
5243 if (errno) {
5244 posix_error();
5245 goto fail;
5246 }
5247 all_flags |= POSIX_SPAWN_SETSIGDEF;
5248 }
5249
5250 if (scheduler) {
5251#ifdef POSIX_SPAWN_SETSCHEDULER
5252 PyObject *py_schedpolicy;
5253 struct sched_param schedparam;
5254
5255 if (!PyArg_ParseTuple(scheduler, "OO&"
5256 ";A scheduler tuple must have two elements",
5257 &py_schedpolicy, convert_sched_param, &schedparam)) {
5258 goto fail;
5259 }
5260 if (py_schedpolicy != Py_None) {
5261 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5262
5263 if (schedpolicy == -1 && PyErr_Occurred()) {
5264 goto fail;
5265 }
5266 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5267 if (errno) {
5268 posix_error();
5269 goto fail;
5270 }
5271 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5272 }
5273 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5274 if (errno) {
5275 posix_error();
5276 goto fail;
5277 }
5278 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5279#else
5280 PyErr_SetString(PyExc_NotImplementedError,
5281 "The scheduler option is not supported in this system.");
5282 goto fail;
5283#endif
5284 }
5285
5286 errno = posix_spawnattr_setflags(attrp, all_flags);
5287 if (errno) {
5288 posix_error();
5289 goto fail;
5290 }
5291
5292 return 0;
5293
5294fail:
5295 (void)posix_spawnattr_destroy(attrp);
5296 return -1;
5297}
5298
5299static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005300parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005301 posix_spawn_file_actions_t *file_actionsp,
5302 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005303{
5304 PyObject *seq;
5305 PyObject *file_action = NULL;
5306 PyObject *tag_obj;
5307
5308 seq = PySequence_Fast(file_actions,
5309 "file_actions must be a sequence or None");
5310 if (seq == NULL) {
5311 return -1;
5312 }
5313
5314 errno = posix_spawn_file_actions_init(file_actionsp);
5315 if (errno) {
5316 posix_error();
5317 Py_DECREF(seq);
5318 return -1;
5319 }
5320
5321 for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
5322 file_action = PySequence_Fast_GET_ITEM(seq, i);
5323 Py_INCREF(file_action);
5324 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5325 PyErr_SetString(PyExc_TypeError,
5326 "Each file_actions element must be a non-empty tuple");
5327 goto fail;
5328 }
5329 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5330 if (tag == -1 && PyErr_Occurred()) {
5331 goto fail;
5332 }
5333
5334 /* Populate the file_actions object */
5335 switch (tag) {
5336 case POSIX_SPAWN_OPEN: {
5337 int fd, oflag;
5338 PyObject *path;
5339 unsigned long mode;
5340 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5341 ";A open file_action tuple must have 5 elements",
5342 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5343 &oflag, &mode))
5344 {
5345 goto fail;
5346 }
Pablo Galindocb970732018-06-19 09:19:50 +01005347 if (PyList_Append(temp_buffer, path)) {
5348 Py_DECREF(path);
5349 goto fail;
5350 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005351 errno = posix_spawn_file_actions_addopen(file_actionsp,
5352 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005353 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005354 if (errno) {
5355 posix_error();
5356 goto fail;
5357 }
5358 break;
5359 }
5360 case POSIX_SPAWN_CLOSE: {
5361 int fd;
5362 if (!PyArg_ParseTuple(file_action, "Oi"
5363 ";A close file_action tuple must have 2 elements",
5364 &tag_obj, &fd))
5365 {
5366 goto fail;
5367 }
5368 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5369 if (errno) {
5370 posix_error();
5371 goto fail;
5372 }
5373 break;
5374 }
5375 case POSIX_SPAWN_DUP2: {
5376 int fd1, fd2;
5377 if (!PyArg_ParseTuple(file_action, "Oii"
5378 ";A dup2 file_action tuple must have 3 elements",
5379 &tag_obj, &fd1, &fd2))
5380 {
5381 goto fail;
5382 }
5383 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5384 fd1, fd2);
5385 if (errno) {
5386 posix_error();
5387 goto fail;
5388 }
5389 break;
5390 }
5391 default: {
5392 PyErr_SetString(PyExc_TypeError,
5393 "Unknown file_actions identifier");
5394 goto fail;
5395 }
5396 }
5397 Py_DECREF(file_action);
5398 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005399
Serhiy Storchakaef347532018-05-01 16:45:04 +03005400 Py_DECREF(seq);
5401 return 0;
5402
5403fail:
5404 Py_DECREF(seq);
5405 Py_DECREF(file_action);
5406 (void)posix_spawn_file_actions_destroy(file_actionsp);
5407 return -1;
5408}
5409
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005410
5411static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005412py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5413 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005414 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005415 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005416{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005417 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005418 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005419 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005420 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005421 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005422 posix_spawnattr_t attr;
5423 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005424 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005425 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005426 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005427 pid_t pid;
5428 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005429
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005430 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005431 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005432 like posix.environ. */
5433
Serhiy Storchakaef347532018-05-01 16:45:04 +03005434 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005435 PyErr_Format(PyExc_TypeError,
5436 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005437 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005438 }
5439 argc = PySequence_Size(argv);
5440 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005441 PyErr_Format(PyExc_ValueError,
5442 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005443 return NULL;
5444 }
5445
5446 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005447 PyErr_Format(PyExc_TypeError,
5448 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005449 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005450 }
5451
5452 argvlist = parse_arglist(argv, &argc);
5453 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005454 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005455 }
5456 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005457 PyErr_Format(PyExc_ValueError,
5458 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005459 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005460 }
5461
5462 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005463 if (envlist == NULL) {
5464 goto exit;
5465 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005466
Serhiy Storchakad700f972018-09-08 14:48:18 +03005467 if (file_actions != NULL) {
Pablo Galindocb970732018-06-19 09:19:50 +01005468 /* There is a bug in old versions of glibc that makes some of the
5469 * helper functions for manipulating file actions not copy the provided
5470 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5471 * copy the value of path for some old versions of glibc (<2.20).
5472 * The use of temp_buffer here is a workaround that keeps the
5473 * python objects that own the buffers alive until posix_spawn gets called.
5474 * Check https://bugs.python.org/issue33630 and
5475 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5476 temp_buffer = PyList_New(0);
5477 if (!temp_buffer) {
5478 goto exit;
5479 }
5480 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005481 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005482 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005483 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005484 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005485
Victor Stinner325e4ba2019-02-01 15:47:24 +01005486 if (parse_posix_spawn_flags(func_name, setpgroup, resetids, setsid,
5487 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005488 goto exit;
5489 }
5490 attrp = &attr;
5491
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005492 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005493#ifdef HAVE_POSIX_SPAWNP
5494 if (use_posix_spawnp) {
5495 err_code = posix_spawnp(&pid, path->narrow,
5496 file_actionsp, attrp, argvlist, envlist);
5497 }
5498 else
5499#endif /* HAVE_POSIX_SPAWNP */
5500 {
5501 err_code = posix_spawn(&pid, path->narrow,
5502 file_actionsp, attrp, argvlist, envlist);
5503 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005504 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005505
Serhiy Storchakaef347532018-05-01 16:45:04 +03005506 if (err_code) {
5507 errno = err_code;
5508 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005509 goto exit;
5510 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005511#ifdef _Py_MEMORY_SANITIZER
5512 __msan_unpoison(&pid, sizeof(pid));
5513#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005514 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005515
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005516exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005517 if (file_actionsp) {
5518 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005519 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005520 if (attrp) {
5521 (void)posix_spawnattr_destroy(attrp);
5522 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005523 if (envlist) {
5524 free_string_array(envlist, envc);
5525 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005526 if (argvlist) {
5527 free_string_array(argvlist, argc);
5528 }
Pablo Galindocb970732018-06-19 09:19:50 +01005529 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005530 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005531}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005532
5533
5534/*[clinic input]
5535
5536os.posix_spawn
5537 path: path_t
5538 Path of executable file.
5539 argv: object
5540 Tuple or list of strings.
5541 env: object
5542 Dictionary of strings mapping to strings.
5543 /
5544 *
5545 file_actions: object(c_default='NULL') = ()
5546 A sequence of file action tuples.
5547 setpgroup: object = NULL
5548 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5549 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005550 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5551 setsid: bool(accept={int}) = False
5552 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005553 setsigmask: object(c_default='NULL') = ()
5554 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5555 setsigdef: object(c_default='NULL') = ()
5556 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5557 scheduler: object = NULL
5558 A tuple with the scheduler policy (optional) and parameters.
5559
5560Execute the program specified by path in a new process.
5561[clinic start generated code]*/
5562
5563static PyObject *
5564os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5565 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005566 PyObject *setpgroup, int resetids, int setsid,
5567 PyObject *setsigmask, PyObject *setsigdef,
5568 PyObject *scheduler)
5569/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005570{
5571 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005572 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005573 scheduler);
5574}
5575 #endif /* HAVE_POSIX_SPAWN */
5576
5577
5578
5579#ifdef HAVE_POSIX_SPAWNP
5580/*[clinic input]
5581
5582os.posix_spawnp
5583 path: path_t
5584 Path of executable file.
5585 argv: object
5586 Tuple or list of strings.
5587 env: object
5588 Dictionary of strings mapping to strings.
5589 /
5590 *
5591 file_actions: object(c_default='NULL') = ()
5592 A sequence of file action tuples.
5593 setpgroup: object = NULL
5594 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5595 resetids: bool(accept={int}) = False
5596 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005597 setsid: bool(accept={int}) = False
5598 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005599 setsigmask: object(c_default='NULL') = ()
5600 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5601 setsigdef: object(c_default='NULL') = ()
5602 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5603 scheduler: object = NULL
5604 A tuple with the scheduler policy (optional) and parameters.
5605
5606Execute the program specified by path in a new process.
5607[clinic start generated code]*/
5608
5609static PyObject *
5610os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5611 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005612 PyObject *setpgroup, int resetids, int setsid,
5613 PyObject *setsigmask, PyObject *setsigdef,
5614 PyObject *scheduler)
5615/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005616{
5617 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005618 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005619 scheduler);
5620}
5621#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005622
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005623
Steve Dowercc16be82016-09-08 10:35:16 -07005624#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005625/*[clinic input]
5626os.spawnv
5627
5628 mode: int
5629 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005630 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005631 Path of executable file.
5632 argv: object
5633 Tuple or list of strings.
5634 /
5635
5636Execute the program specified by path in a new process.
5637[clinic start generated code]*/
5638
Larry Hastings2f936352014-08-05 14:04:04 +10005639static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005640os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5641/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005642{
Steve Dowercc16be82016-09-08 10:35:16 -07005643 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005644 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005645 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005646 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005647 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005648
Victor Stinner8c62be82010-05-06 00:08:46 +00005649 /* spawnv has three arguments: (mode, path, argv), where
5650 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005651
Victor Stinner8c62be82010-05-06 00:08:46 +00005652 if (PyList_Check(argv)) {
5653 argc = PyList_Size(argv);
5654 getitem = PyList_GetItem;
5655 }
5656 else if (PyTuple_Check(argv)) {
5657 argc = PyTuple_Size(argv);
5658 getitem = PyTuple_GetItem;
5659 }
5660 else {
5661 PyErr_SetString(PyExc_TypeError,
5662 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005663 return NULL;
5664 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005665 if (argc == 0) {
5666 PyErr_SetString(PyExc_ValueError,
5667 "spawnv() arg 2 cannot be empty");
5668 return NULL;
5669 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005670
Steve Dowercc16be82016-09-08 10:35:16 -07005671 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005672 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005673 return PyErr_NoMemory();
5674 }
5675 for (i = 0; i < argc; i++) {
5676 if (!fsconvert_strdup((*getitem)(argv, i),
5677 &argvlist[i])) {
5678 free_string_array(argvlist, i);
5679 PyErr_SetString(
5680 PyExc_TypeError,
5681 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005682 return NULL;
5683 }
Steve Dower93ff8722016-11-19 19:03:54 -08005684 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005685 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005686 PyErr_SetString(
5687 PyExc_ValueError,
5688 "spawnv() arg 2 first element cannot be empty");
5689 return NULL;
5690 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005691 }
5692 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005693
Victor Stinner8c62be82010-05-06 00:08:46 +00005694 if (mode == _OLD_P_OVERLAY)
5695 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005696
Victor Stinner8c62be82010-05-06 00:08:46 +00005697 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005698 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005699#ifdef HAVE_WSPAWNV
5700 spawnval = _wspawnv(mode, path->wide, argvlist);
5701#else
5702 spawnval = _spawnv(mode, path->narrow, argvlist);
5703#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005704 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005705 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005706
Victor Stinner8c62be82010-05-06 00:08:46 +00005707 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005708
Victor Stinner8c62be82010-05-06 00:08:46 +00005709 if (spawnval == -1)
5710 return posix_error();
5711 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005712 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005713}
5714
Larry Hastings2f936352014-08-05 14:04:04 +10005715/*[clinic input]
5716os.spawnve
5717
5718 mode: int
5719 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005720 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005721 Path of executable file.
5722 argv: object
5723 Tuple or list of strings.
5724 env: object
5725 Dictionary of strings mapping to strings.
5726 /
5727
5728Execute the program specified by path in a new process.
5729[clinic start generated code]*/
5730
Larry Hastings2f936352014-08-05 14:04:04 +10005731static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005732os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005733 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005734/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005735{
Steve Dowercc16be82016-09-08 10:35:16 -07005736 EXECV_CHAR **argvlist;
5737 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005738 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005739 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005740 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005741 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005742 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005743
Victor Stinner8c62be82010-05-06 00:08:46 +00005744 /* spawnve has four arguments: (mode, path, argv, env), where
5745 argv is a list or tuple of strings and env is a dictionary
5746 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005747
Victor Stinner8c62be82010-05-06 00:08:46 +00005748 if (PyList_Check(argv)) {
5749 argc = PyList_Size(argv);
5750 getitem = PyList_GetItem;
5751 }
5752 else if (PyTuple_Check(argv)) {
5753 argc = PyTuple_Size(argv);
5754 getitem = PyTuple_GetItem;
5755 }
5756 else {
5757 PyErr_SetString(PyExc_TypeError,
5758 "spawnve() arg 2 must be a tuple or list");
5759 goto fail_0;
5760 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005761 if (argc == 0) {
5762 PyErr_SetString(PyExc_ValueError,
5763 "spawnve() arg 2 cannot be empty");
5764 goto fail_0;
5765 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005766 if (!PyMapping_Check(env)) {
5767 PyErr_SetString(PyExc_TypeError,
5768 "spawnve() arg 3 must be a mapping object");
5769 goto fail_0;
5770 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005771
Steve Dowercc16be82016-09-08 10:35:16 -07005772 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005773 if (argvlist == NULL) {
5774 PyErr_NoMemory();
5775 goto fail_0;
5776 }
5777 for (i = 0; i < argc; i++) {
5778 if (!fsconvert_strdup((*getitem)(argv, i),
5779 &argvlist[i]))
5780 {
5781 lastarg = i;
5782 goto fail_1;
5783 }
Steve Dowerbce26262016-11-19 19:17:26 -08005784 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005785 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005786 PyErr_SetString(
5787 PyExc_ValueError,
5788 "spawnv() arg 2 first element cannot be empty");
5789 goto fail_1;
5790 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005791 }
5792 lastarg = argc;
5793 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005794
Victor Stinner8c62be82010-05-06 00:08:46 +00005795 envlist = parse_envlist(env, &envc);
5796 if (envlist == NULL)
5797 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005798
Victor Stinner8c62be82010-05-06 00:08:46 +00005799 if (mode == _OLD_P_OVERLAY)
5800 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005801
Victor Stinner8c62be82010-05-06 00:08:46 +00005802 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005803 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005804#ifdef HAVE_WSPAWNV
5805 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5806#else
5807 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5808#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005809 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005810 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005811
Victor Stinner8c62be82010-05-06 00:08:46 +00005812 if (spawnval == -1)
5813 (void) posix_error();
5814 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005815 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005816
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 while (--envc >= 0)
5818 PyMem_DEL(envlist[envc]);
5819 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005820 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005821 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005822 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005823 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005824}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005825
Guido van Rossuma1065681999-01-25 23:20:23 +00005826#endif /* HAVE_SPAWNV */
5827
5828
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005829#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005830
5831/* Helper function to validate arguments.
5832 Returns 0 on success. non-zero on failure with a TypeError raised.
5833 If obj is non-NULL it must be callable. */
5834static int
5835check_null_or_callable(PyObject *obj, const char* obj_name)
5836{
5837 if (obj && !PyCallable_Check(obj)) {
5838 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5839 obj_name, Py_TYPE(obj)->tp_name);
5840 return -1;
5841 }
5842 return 0;
5843}
5844
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005845/*[clinic input]
5846os.register_at_fork
5847
Gregory P. Smith163468a2017-05-29 10:03:41 -07005848 *
5849 before: object=NULL
5850 A callable to be called in the parent before the fork() syscall.
5851 after_in_child: object=NULL
5852 A callable to be called in the child after fork().
5853 after_in_parent: object=NULL
5854 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005855
Gregory P. Smith163468a2017-05-29 10:03:41 -07005856Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005857
Gregory P. Smith163468a2017-05-29 10:03:41 -07005858'before' callbacks are called in reverse order.
5859'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005860
5861[clinic start generated code]*/
5862
5863static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005864os_register_at_fork_impl(PyObject *module, PyObject *before,
5865 PyObject *after_in_child, PyObject *after_in_parent)
5866/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005867{
5868 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005869
Gregory P. Smith163468a2017-05-29 10:03:41 -07005870 if (!before && !after_in_child && !after_in_parent) {
5871 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5872 return NULL;
5873 }
5874 if (check_null_or_callable(before, "before") ||
5875 check_null_or_callable(after_in_child, "after_in_child") ||
5876 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005877 return NULL;
5878 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02005879 interp = _PyInterpreterState_Get();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005880
Gregory P. Smith163468a2017-05-29 10:03:41 -07005881 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005882 return NULL;
5883 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005884 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005885 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005886 }
5887 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5888 return NULL;
5889 }
5890 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005891}
5892#endif /* HAVE_FORK */
5893
5894
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005895#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005896/*[clinic input]
5897os.fork1
5898
5899Fork a child process with a single multiplexed (i.e., not bound) thread.
5900
5901Return 0 to child process and PID of child to parent process.
5902[clinic start generated code]*/
5903
Larry Hastings2f936352014-08-05 14:04:04 +10005904static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005905os_fork1_impl(PyObject *module)
5906/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005907{
Victor Stinner8c62be82010-05-06 00:08:46 +00005908 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005909
Eric Snow59032962018-09-14 14:17:20 -07005910 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5911 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5912 return NULL;
5913 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005914 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005915 pid = fork1();
5916 if (pid == 0) {
5917 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005918 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005919 } else {
5920 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005921 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005922 }
5923 if (pid == -1)
5924 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005926}
Larry Hastings2f936352014-08-05 14:04:04 +10005927#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005928
5929
Guido van Rossumad0ee831995-03-01 10:34:45 +00005930#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005931/*[clinic input]
5932os.fork
5933
5934Fork a child process.
5935
5936Return 0 to child process and PID of child to parent process.
5937[clinic start generated code]*/
5938
Larry Hastings2f936352014-08-05 14:04:04 +10005939static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005940os_fork_impl(PyObject *module)
5941/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005942{
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005944
Eric Snow59032962018-09-14 14:17:20 -07005945 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
5946 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
5947 return NULL;
5948 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005949 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 pid = fork();
5951 if (pid == 0) {
5952 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005953 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005954 } else {
5955 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005956 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005957 }
5958 if (pid == -1)
5959 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005960 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005961}
Larry Hastings2f936352014-08-05 14:04:04 +10005962#endif /* HAVE_FORK */
5963
Guido van Rossum85e3b011991-06-03 12:42:10 +00005964
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005965#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005966#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005967/*[clinic input]
5968os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005969
Larry Hastings2f936352014-08-05 14:04:04 +10005970 policy: int
5971
5972Get the maximum scheduling priority for policy.
5973[clinic start generated code]*/
5974
Larry Hastings2f936352014-08-05 14:04:04 +10005975static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005976os_sched_get_priority_max_impl(PyObject *module, int policy)
5977/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005978{
5979 int max;
5980
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005981 max = sched_get_priority_max(policy);
5982 if (max < 0)
5983 return posix_error();
5984 return PyLong_FromLong(max);
5985}
5986
Larry Hastings2f936352014-08-05 14:04:04 +10005987
5988/*[clinic input]
5989os.sched_get_priority_min
5990
5991 policy: int
5992
5993Get the minimum scheduling priority for policy.
5994[clinic start generated code]*/
5995
Larry Hastings2f936352014-08-05 14:04:04 +10005996static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005997os_sched_get_priority_min_impl(PyObject *module, int policy)
5998/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005999{
6000 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006001 if (min < 0)
6002 return posix_error();
6003 return PyLong_FromLong(min);
6004}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006005#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6006
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006007
Larry Hastings2f936352014-08-05 14:04:04 +10006008#ifdef HAVE_SCHED_SETSCHEDULER
6009/*[clinic input]
6010os.sched_getscheduler
6011 pid: pid_t
6012 /
6013
6014Get the scheduling policy for the process identifiedy by pid.
6015
6016Passing 0 for pid returns the scheduling policy for the calling process.
6017[clinic start generated code]*/
6018
Larry Hastings2f936352014-08-05 14:04:04 +10006019static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006020os_sched_getscheduler_impl(PyObject *module, pid_t pid)
6021/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006022{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006023 int policy;
6024
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006025 policy = sched_getscheduler(pid);
6026 if (policy < 0)
6027 return posix_error();
6028 return PyLong_FromLong(policy);
6029}
Larry Hastings2f936352014-08-05 14:04:04 +10006030#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006031
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006032
William Orr81574b82018-10-01 22:19:56 -07006033#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006034/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006035class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006036
6037@classmethod
6038os.sched_param.__new__
6039
6040 sched_priority: object
6041 A scheduling parameter.
6042
6043Current has only one field: sched_priority");
6044[clinic start generated code]*/
6045
Larry Hastings2f936352014-08-05 14:04:04 +10006046static PyObject *
6047os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006048/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006049{
6050 PyObject *res;
6051
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006052 res = PyStructSequence_New(type);
6053 if (!res)
6054 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006055 Py_INCREF(sched_priority);
6056 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006057 return res;
6058}
6059
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006060
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006061PyDoc_VAR(os_sched_param__doc__);
6062
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006063static PyStructSequence_Field sched_param_fields[] = {
6064 {"sched_priority", "the scheduling priority"},
6065 {0}
6066};
6067
6068static PyStructSequence_Desc sched_param_desc = {
6069 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006070 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006071 sched_param_fields,
6072 1
6073};
6074
6075static int
6076convert_sched_param(PyObject *param, struct sched_param *res)
6077{
6078 long priority;
6079
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006080 if (Py_TYPE(param) != SchedParamType) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006081 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6082 return 0;
6083 }
6084 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6085 if (priority == -1 && PyErr_Occurred())
6086 return 0;
6087 if (priority > INT_MAX || priority < INT_MIN) {
6088 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6089 return 0;
6090 }
6091 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6092 return 1;
6093}
William Orr81574b82018-10-01 22:19:56 -07006094#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006095
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006096
6097#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006098/*[clinic input]
6099os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006100
Larry Hastings2f936352014-08-05 14:04:04 +10006101 pid: pid_t
6102 policy: int
6103 param: sched_param
6104 /
6105
6106Set the scheduling policy for the process identified by pid.
6107
6108If pid is 0, the calling process is changed.
6109param is an instance of sched_param.
6110[clinic start generated code]*/
6111
Larry Hastings2f936352014-08-05 14:04:04 +10006112static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006113os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04006114 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006115/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006116{
Jesus Cea9c822272011-09-10 01:40:52 +02006117 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006118 ** sched_setscheduler() returns 0 in Linux, but the previous
6119 ** scheduling policy under Solaris/Illumos, and others.
6120 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006121 */
Larry Hastings2f936352014-08-05 14:04:04 +10006122 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006123 return posix_error();
6124 Py_RETURN_NONE;
6125}
Larry Hastings2f936352014-08-05 14:04:04 +10006126#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006127
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006128
6129#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006130/*[clinic input]
6131os.sched_getparam
6132 pid: pid_t
6133 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006134
Larry Hastings2f936352014-08-05 14:04:04 +10006135Returns scheduling parameters for the process identified by pid.
6136
6137If pid is 0, returns parameters for the calling process.
6138Return value is an instance of sched_param.
6139[clinic start generated code]*/
6140
Larry Hastings2f936352014-08-05 14:04:04 +10006141static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006142os_sched_getparam_impl(PyObject *module, pid_t pid)
6143/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006144{
6145 struct sched_param param;
6146 PyObject *result;
6147 PyObject *priority;
6148
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006149 if (sched_getparam(pid, &param))
6150 return posix_error();
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006151 result = PyStructSequence_New(SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006152 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006153 return NULL;
6154 priority = PyLong_FromLong(param.sched_priority);
6155 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006156 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006157 return NULL;
6158 }
Larry Hastings2f936352014-08-05 14:04:04 +10006159 PyStructSequence_SET_ITEM(result, 0, priority);
6160 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006161}
6162
Larry Hastings2f936352014-08-05 14:04:04 +10006163
6164/*[clinic input]
6165os.sched_setparam
6166 pid: pid_t
6167 param: sched_param
6168 /
6169
6170Set scheduling parameters for the process identified by pid.
6171
6172If pid is 0, sets parameters for the calling process.
6173param should be an instance of sched_param.
6174[clinic start generated code]*/
6175
Larry Hastings2f936352014-08-05 14:04:04 +10006176static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006177os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04006178 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006179/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006180{
6181 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006182 return posix_error();
6183 Py_RETURN_NONE;
6184}
Larry Hastings2f936352014-08-05 14:04:04 +10006185#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006186
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006187
6188#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006189/*[clinic input]
6190os.sched_rr_get_interval -> double
6191 pid: pid_t
6192 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006193
Larry Hastings2f936352014-08-05 14:04:04 +10006194Return the round-robin quantum for the process identified by pid, in seconds.
6195
6196Value returned is a float.
6197[clinic start generated code]*/
6198
Larry Hastings2f936352014-08-05 14:04:04 +10006199static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006200os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6201/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006202{
6203 struct timespec interval;
6204 if (sched_rr_get_interval(pid, &interval)) {
6205 posix_error();
6206 return -1.0;
6207 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006208#ifdef _Py_MEMORY_SANITIZER
6209 __msan_unpoison(&interval, sizeof(interval));
6210#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006211 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6212}
6213#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006214
Larry Hastings2f936352014-08-05 14:04:04 +10006215
6216/*[clinic input]
6217os.sched_yield
6218
6219Voluntarily relinquish the CPU.
6220[clinic start generated code]*/
6221
Larry Hastings2f936352014-08-05 14:04:04 +10006222static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006223os_sched_yield_impl(PyObject *module)
6224/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006225{
6226 if (sched_yield())
6227 return posix_error();
6228 Py_RETURN_NONE;
6229}
6230
Benjamin Peterson2740af82011-08-02 17:41:34 -05006231#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006232/* The minimum number of CPUs allocated in a cpu_set_t */
6233static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006234
Larry Hastings2f936352014-08-05 14:04:04 +10006235/*[clinic input]
6236os.sched_setaffinity
6237 pid: pid_t
6238 mask : object
6239 /
6240
6241Set the CPU affinity of the process identified by pid to mask.
6242
6243mask should be an iterable of integers identifying CPUs.
6244[clinic start generated code]*/
6245
Larry Hastings2f936352014-08-05 14:04:04 +10006246static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006247os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6248/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006249{
Antoine Pitrou84869872012-08-04 16:16:35 +02006250 int ncpus;
6251 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006252 cpu_set_t *cpu_set = NULL;
6253 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006254
Larry Hastings2f936352014-08-05 14:04:04 +10006255 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006256 if (iterator == NULL)
6257 return NULL;
6258
6259 ncpus = NCPUS_START;
6260 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006261 cpu_set = CPU_ALLOC(ncpus);
6262 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006263 PyErr_NoMemory();
6264 goto error;
6265 }
Larry Hastings2f936352014-08-05 14:04:04 +10006266 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006267
6268 while ((item = PyIter_Next(iterator))) {
6269 long cpu;
6270 if (!PyLong_Check(item)) {
6271 PyErr_Format(PyExc_TypeError,
6272 "expected an iterator of ints, "
6273 "but iterator yielded %R",
6274 Py_TYPE(item));
6275 Py_DECREF(item);
6276 goto error;
6277 }
6278 cpu = PyLong_AsLong(item);
6279 Py_DECREF(item);
6280 if (cpu < 0) {
6281 if (!PyErr_Occurred())
6282 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6283 goto error;
6284 }
6285 if (cpu > INT_MAX - 1) {
6286 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6287 goto error;
6288 }
6289 if (cpu >= ncpus) {
6290 /* Grow CPU mask to fit the CPU number */
6291 int newncpus = ncpus;
6292 cpu_set_t *newmask;
6293 size_t newsetsize;
6294 while (newncpus <= cpu) {
6295 if (newncpus > INT_MAX / 2)
6296 newncpus = cpu + 1;
6297 else
6298 newncpus = newncpus * 2;
6299 }
6300 newmask = CPU_ALLOC(newncpus);
6301 if (newmask == NULL) {
6302 PyErr_NoMemory();
6303 goto error;
6304 }
6305 newsetsize = CPU_ALLOC_SIZE(newncpus);
6306 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006307 memcpy(newmask, cpu_set, setsize);
6308 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006309 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006310 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006311 ncpus = newncpus;
6312 }
Larry Hastings2f936352014-08-05 14:04:04 +10006313 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006314 }
6315 Py_CLEAR(iterator);
6316
Larry Hastings2f936352014-08-05 14:04:04 +10006317 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006318 posix_error();
6319 goto error;
6320 }
Larry Hastings2f936352014-08-05 14:04:04 +10006321 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006322 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006323
6324error:
Larry Hastings2f936352014-08-05 14:04:04 +10006325 if (cpu_set)
6326 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006327 Py_XDECREF(iterator);
6328 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006329}
6330
Larry Hastings2f936352014-08-05 14:04:04 +10006331
6332/*[clinic input]
6333os.sched_getaffinity
6334 pid: pid_t
6335 /
6336
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006337Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006338
6339The affinity is returned as a set of CPU identifiers.
6340[clinic start generated code]*/
6341
Larry Hastings2f936352014-08-05 14:04:04 +10006342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006343os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006344/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006345{
Antoine Pitrou84869872012-08-04 16:16:35 +02006346 int cpu, ncpus, count;
6347 size_t setsize;
6348 cpu_set_t *mask = NULL;
6349 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006350
Antoine Pitrou84869872012-08-04 16:16:35 +02006351 ncpus = NCPUS_START;
6352 while (1) {
6353 setsize = CPU_ALLOC_SIZE(ncpus);
6354 mask = CPU_ALLOC(ncpus);
6355 if (mask == NULL)
6356 return PyErr_NoMemory();
6357 if (sched_getaffinity(pid, setsize, mask) == 0)
6358 break;
6359 CPU_FREE(mask);
6360 if (errno != EINVAL)
6361 return posix_error();
6362 if (ncpus > INT_MAX / 2) {
6363 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6364 "a large enough CPU set");
6365 return NULL;
6366 }
6367 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006368 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006369
6370 res = PySet_New(NULL);
6371 if (res == NULL)
6372 goto error;
6373 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6374 if (CPU_ISSET_S(cpu, setsize, mask)) {
6375 PyObject *cpu_num = PyLong_FromLong(cpu);
6376 --count;
6377 if (cpu_num == NULL)
6378 goto error;
6379 if (PySet_Add(res, cpu_num)) {
6380 Py_DECREF(cpu_num);
6381 goto error;
6382 }
6383 Py_DECREF(cpu_num);
6384 }
6385 }
6386 CPU_FREE(mask);
6387 return res;
6388
6389error:
6390 if (mask)
6391 CPU_FREE(mask);
6392 Py_XDECREF(res);
6393 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006394}
6395
Benjamin Peterson2740af82011-08-02 17:41:34 -05006396#endif /* HAVE_SCHED_SETAFFINITY */
6397
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006398#endif /* HAVE_SCHED_H */
6399
Larry Hastings2f936352014-08-05 14:04:04 +10006400
Neal Norwitzb59798b2003-03-21 01:43:31 +00006401/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006402/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6403#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006404#define DEV_PTY_FILE "/dev/ptc"
6405#define HAVE_DEV_PTMX
6406#else
6407#define DEV_PTY_FILE "/dev/ptmx"
6408#endif
6409
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006410#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006411#ifdef HAVE_PTY_H
6412#include <pty.h>
6413#else
6414#ifdef HAVE_LIBUTIL_H
6415#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006416#else
6417#ifdef HAVE_UTIL_H
6418#include <util.h>
6419#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006420#endif /* HAVE_LIBUTIL_H */
6421#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006422#ifdef HAVE_STROPTS_H
6423#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006424#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006425#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006426
Larry Hastings2f936352014-08-05 14:04:04 +10006427
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006428#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006429/*[clinic input]
6430os.openpty
6431
6432Open a pseudo-terminal.
6433
6434Return a tuple of (master_fd, slave_fd) containing open file descriptors
6435for both the master and slave ends.
6436[clinic start generated code]*/
6437
Larry Hastings2f936352014-08-05 14:04:04 +10006438static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006439os_openpty_impl(PyObject *module)
6440/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006441{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006442 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006443#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006444 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006445#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006446#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006447 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006448#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006450#endif
6451#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006452
Thomas Wouters70c21a12000-07-14 14:28:33 +00006453#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006454 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006455 goto posix_error;
6456
6457 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6458 goto error;
6459 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6460 goto error;
6461
Neal Norwitzb59798b2003-03-21 01:43:31 +00006462#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006463 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6464 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006465 goto posix_error;
6466 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6467 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006468
Victor Stinnerdaf45552013-08-28 00:53:59 +02006469 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006470 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006471 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006472
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006473#else
Victor Stinner000de532013-11-25 23:19:58 +01006474 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006475 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006476 goto posix_error;
6477
Victor Stinner8c62be82010-05-06 00:08:46 +00006478 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006479
Victor Stinner8c62be82010-05-06 00:08:46 +00006480 /* change permission of slave */
6481 if (grantpt(master_fd) < 0) {
6482 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006483 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006485
Victor Stinner8c62be82010-05-06 00:08:46 +00006486 /* unlock slave */
6487 if (unlockpt(master_fd) < 0) {
6488 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006489 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006490 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006491
Victor Stinner8c62be82010-05-06 00:08:46 +00006492 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006493
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 slave_name = ptsname(master_fd); /* get name of slave */
6495 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006496 goto posix_error;
6497
6498 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006499 if (slave_fd == -1)
6500 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006501
6502 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6503 goto posix_error;
6504
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006505#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6507 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006508#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006510#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006511#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006512#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006513
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006515
Victor Stinnerdaf45552013-08-28 00:53:59 +02006516posix_error:
6517 posix_error();
6518error:
6519 if (master_fd != -1)
6520 close(master_fd);
6521 if (slave_fd != -1)
6522 close(slave_fd);
6523 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006524}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006525#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006526
Larry Hastings2f936352014-08-05 14:04:04 +10006527
Fred Drake8cef4cf2000-06-28 16:40:38 +00006528#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006529/*[clinic input]
6530os.forkpty
6531
6532Fork a new process with a new pseudo-terminal as controlling tty.
6533
6534Returns a tuple of (pid, master_fd).
6535Like fork(), return pid of 0 to the child process,
6536and pid of child to the parent process.
6537To both, return fd of newly opened pseudo-terminal.
6538[clinic start generated code]*/
6539
Larry Hastings2f936352014-08-05 14:04:04 +10006540static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006541os_forkpty_impl(PyObject *module)
6542/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006543{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006544 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006546
Eric Snow59032962018-09-14 14:17:20 -07006547 if (_PyInterpreterState_Get() != PyInterpreterState_Main()) {
6548 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6549 return NULL;
6550 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006551 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 pid = forkpty(&master_fd, NULL, NULL, NULL);
6553 if (pid == 0) {
6554 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006555 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006556 } else {
6557 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006558 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 }
6560 if (pid == -1)
6561 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006563}
Larry Hastings2f936352014-08-05 14:04:04 +10006564#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006565
Ross Lagerwall7807c352011-03-17 20:20:30 +02006566
Guido van Rossumad0ee831995-03-01 10:34:45 +00006567#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006568/*[clinic input]
6569os.getegid
6570
6571Return the current process's effective group id.
6572[clinic start generated code]*/
6573
Larry Hastings2f936352014-08-05 14:04:04 +10006574static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006575os_getegid_impl(PyObject *module)
6576/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006577{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006578 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006579}
Larry Hastings2f936352014-08-05 14:04:04 +10006580#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006582
Guido van Rossumad0ee831995-03-01 10:34:45 +00006583#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006584/*[clinic input]
6585os.geteuid
6586
6587Return the current process's effective user id.
6588[clinic start generated code]*/
6589
Larry Hastings2f936352014-08-05 14:04:04 +10006590static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006591os_geteuid_impl(PyObject *module)
6592/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006593{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006594 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006595}
Larry Hastings2f936352014-08-05 14:04:04 +10006596#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006597
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006598
Guido van Rossumad0ee831995-03-01 10:34:45 +00006599#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006600/*[clinic input]
6601os.getgid
6602
6603Return the current process's group id.
6604[clinic start generated code]*/
6605
Larry Hastings2f936352014-08-05 14:04:04 +10006606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006607os_getgid_impl(PyObject *module)
6608/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006609{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006610 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006611}
Larry Hastings2f936352014-08-05 14:04:04 +10006612#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006614
Berker Peksag39404992016-09-15 20:45:16 +03006615#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006616/*[clinic input]
6617os.getpid
6618
6619Return the current process id.
6620[clinic start generated code]*/
6621
Larry Hastings2f936352014-08-05 14:04:04 +10006622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006623os_getpid_impl(PyObject *module)
6624/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006625{
Victor Stinner8c62be82010-05-06 00:08:46 +00006626 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006627}
Berker Peksag39404992016-09-15 20:45:16 +03006628#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006629
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006630#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006631
6632/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006633PyDoc_STRVAR(posix_getgrouplist__doc__,
6634"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6635Returns a list of groups to which a user belongs.\n\n\
6636 user: username to lookup\n\
6637 group: base group id of the user");
6638
6639static PyObject *
6640posix_getgrouplist(PyObject *self, PyObject *args)
6641{
6642#ifdef NGROUPS_MAX
6643#define MAX_GROUPS NGROUPS_MAX
6644#else
6645 /* defined to be 16 on Solaris7, so this should be a small number */
6646#define MAX_GROUPS 64
6647#endif
6648
6649 const char *user;
6650 int i, ngroups;
6651 PyObject *list;
6652#ifdef __APPLE__
6653 int *groups, basegid;
6654#else
6655 gid_t *groups, basegid;
6656#endif
6657 ngroups = MAX_GROUPS;
6658
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006659#ifdef __APPLE__
6660 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006661 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006662#else
6663 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6664 _Py_Gid_Converter, &basegid))
6665 return NULL;
6666#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006667
6668#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006669 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006670#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006671 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006672#endif
6673 if (groups == NULL)
6674 return PyErr_NoMemory();
6675
6676 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6677 PyMem_Del(groups);
6678 return posix_error();
6679 }
6680
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006681#ifdef _Py_MEMORY_SANITIZER
6682 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6683 __msan_unpoison(&ngroups, sizeof(ngroups));
6684 __msan_unpoison(groups, ngroups*sizeof(*groups));
6685#endif
6686
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006687 list = PyList_New(ngroups);
6688 if (list == NULL) {
6689 PyMem_Del(groups);
6690 return NULL;
6691 }
6692
6693 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006694#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006695 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006696#else
6697 PyObject *o = _PyLong_FromGid(groups[i]);
6698#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006699 if (o == NULL) {
6700 Py_DECREF(list);
6701 PyMem_Del(groups);
6702 return NULL;
6703 }
6704 PyList_SET_ITEM(list, i, o);
6705 }
6706
6707 PyMem_Del(groups);
6708
6709 return list;
6710}
Larry Hastings2f936352014-08-05 14:04:04 +10006711#endif /* HAVE_GETGROUPLIST */
6712
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006713
Fred Drakec9680921999-12-13 16:37:25 +00006714#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006715/*[clinic input]
6716os.getgroups
6717
6718Return list of supplemental group IDs for the process.
6719[clinic start generated code]*/
6720
Larry Hastings2f936352014-08-05 14:04:04 +10006721static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006722os_getgroups_impl(PyObject *module)
6723/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006724{
6725 PyObject *result = NULL;
6726
Fred Drakec9680921999-12-13 16:37:25 +00006727#ifdef NGROUPS_MAX
6728#define MAX_GROUPS NGROUPS_MAX
6729#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006730 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006731#define MAX_GROUPS 64
6732#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006733 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006734
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006735 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006736 * This is a helper variable to store the intermediate result when
6737 * that happens.
6738 *
6739 * To keep the code readable the OSX behaviour is unconditional,
6740 * according to the POSIX spec this should be safe on all unix-y
6741 * systems.
6742 */
6743 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006744 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006745
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006746#ifdef __APPLE__
6747 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6748 * there are more groups than can fit in grouplist. Therefore, on OS X
6749 * always first call getgroups with length 0 to get the actual number
6750 * of groups.
6751 */
6752 n = getgroups(0, NULL);
6753 if (n < 0) {
6754 return posix_error();
6755 } else if (n <= MAX_GROUPS) {
6756 /* groups will fit in existing array */
6757 alt_grouplist = grouplist;
6758 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006759 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006760 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006761 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006762 }
6763 }
6764
6765 n = getgroups(n, alt_grouplist);
6766 if (n == -1) {
6767 if (alt_grouplist != grouplist) {
6768 PyMem_Free(alt_grouplist);
6769 }
6770 return posix_error();
6771 }
6772#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006774 if (n < 0) {
6775 if (errno == EINVAL) {
6776 n = getgroups(0, NULL);
6777 if (n == -1) {
6778 return posix_error();
6779 }
6780 if (n == 0) {
6781 /* Avoid malloc(0) */
6782 alt_grouplist = grouplist;
6783 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006784 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006785 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07006786 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006787 }
6788 n = getgroups(n, alt_grouplist);
6789 if (n == -1) {
6790 PyMem_Free(alt_grouplist);
6791 return posix_error();
6792 }
6793 }
6794 } else {
6795 return posix_error();
6796 }
6797 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006798#endif
6799
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006800 result = PyList_New(n);
6801 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 int i;
6803 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006804 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006806 Py_DECREF(result);
6807 result = NULL;
6808 break;
Fred Drakec9680921999-12-13 16:37:25 +00006809 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006810 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006811 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006812 }
6813
6814 if (alt_grouplist != grouplist) {
6815 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006816 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006817
Fred Drakec9680921999-12-13 16:37:25 +00006818 return result;
6819}
Larry Hastings2f936352014-08-05 14:04:04 +10006820#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006821
Antoine Pitroub7572f02009-12-02 20:46:48 +00006822#ifdef HAVE_INITGROUPS
6823PyDoc_STRVAR(posix_initgroups__doc__,
6824"initgroups(username, gid) -> None\n\n\
6825Call the system initgroups() to initialize the group access list with all of\n\
6826the groups of which the specified username is a member, plus the specified\n\
6827group id.");
6828
Larry Hastings2f936352014-08-05 14:04:04 +10006829/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006830static PyObject *
6831posix_initgroups(PyObject *self, PyObject *args)
6832{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006833 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006834 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006835 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006836#ifdef __APPLE__
6837 int gid;
6838#else
6839 gid_t gid;
6840#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006841
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006842#ifdef __APPLE__
6843 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6844 PyUnicode_FSConverter, &oname,
6845 &gid))
6846#else
6847 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6848 PyUnicode_FSConverter, &oname,
6849 _Py_Gid_Converter, &gid))
6850#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006852 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006853
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006854 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006855 Py_DECREF(oname);
6856 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006858
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006859 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006860}
Larry Hastings2f936352014-08-05 14:04:04 +10006861#endif /* HAVE_INITGROUPS */
6862
Antoine Pitroub7572f02009-12-02 20:46:48 +00006863
Martin v. Löwis606edc12002-06-13 21:09:11 +00006864#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006865/*[clinic input]
6866os.getpgid
6867
6868 pid: pid_t
6869
6870Call the system call getpgid(), and return the result.
6871[clinic start generated code]*/
6872
Larry Hastings2f936352014-08-05 14:04:04 +10006873static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006874os_getpgid_impl(PyObject *module, pid_t pid)
6875/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006876{
6877 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 if (pgid < 0)
6879 return posix_error();
6880 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006881}
6882#endif /* HAVE_GETPGID */
6883
6884
Guido van Rossumb6775db1994-08-01 11:34:53 +00006885#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006886/*[clinic input]
6887os.getpgrp
6888
6889Return the current process group id.
6890[clinic start generated code]*/
6891
Larry Hastings2f936352014-08-05 14:04:04 +10006892static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006893os_getpgrp_impl(PyObject *module)
6894/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006895{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006896#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006897 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006898#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006900#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006901}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006902#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006903
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006904
Guido van Rossumb6775db1994-08-01 11:34:53 +00006905#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006906/*[clinic input]
6907os.setpgrp
6908
6909Make the current process the leader of its process group.
6910[clinic start generated code]*/
6911
Larry Hastings2f936352014-08-05 14:04:04 +10006912static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006913os_setpgrp_impl(PyObject *module)
6914/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006915{
Guido van Rossum64933891994-10-20 21:56:42 +00006916#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006917 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006918#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006920#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006921 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006922 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006923}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006924#endif /* HAVE_SETPGRP */
6925
Guido van Rossumad0ee831995-03-01 10:34:45 +00006926#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006927
6928#ifdef MS_WINDOWS
6929#include <tlhelp32.h>
6930
6931static PyObject*
6932win32_getppid()
6933{
6934 HANDLE snapshot;
6935 pid_t mypid;
6936 PyObject* result = NULL;
6937 BOOL have_record;
6938 PROCESSENTRY32 pe;
6939
6940 mypid = getpid(); /* This function never fails */
6941
6942 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6943 if (snapshot == INVALID_HANDLE_VALUE)
6944 return PyErr_SetFromWindowsErr(GetLastError());
6945
6946 pe.dwSize = sizeof(pe);
6947 have_record = Process32First(snapshot, &pe);
6948 while (have_record) {
6949 if (mypid == (pid_t)pe.th32ProcessID) {
6950 /* We could cache the ulong value in a static variable. */
6951 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6952 break;
6953 }
6954
6955 have_record = Process32Next(snapshot, &pe);
6956 }
6957
6958 /* If our loop exits and our pid was not found (result will be NULL)
6959 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6960 * error anyway, so let's raise it. */
6961 if (!result)
6962 result = PyErr_SetFromWindowsErr(GetLastError());
6963
6964 CloseHandle(snapshot);
6965
6966 return result;
6967}
6968#endif /*MS_WINDOWS*/
6969
Larry Hastings2f936352014-08-05 14:04:04 +10006970
6971/*[clinic input]
6972os.getppid
6973
6974Return the parent's process id.
6975
6976If the parent process has already exited, Windows machines will still
6977return its id; others systems will return the id of the 'init' process (1).
6978[clinic start generated code]*/
6979
Larry Hastings2f936352014-08-05 14:04:04 +10006980static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006981os_getppid_impl(PyObject *module)
6982/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006983{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006984#ifdef MS_WINDOWS
6985 return win32_getppid();
6986#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006987 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006988#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006989}
6990#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006991
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006992
Fred Drake12c6e2d1999-12-14 21:25:03 +00006993#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006994/*[clinic input]
6995os.getlogin
6996
6997Return the actual login name.
6998[clinic start generated code]*/
6999
Larry Hastings2f936352014-08-05 14:04:04 +10007000static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007001os_getlogin_impl(PyObject *module)
7002/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007003{
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007005#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007006 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007007 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007008
7009 if (GetUserNameW(user_name, &num_chars)) {
7010 /* num_chars is the number of unicode chars plus null terminator */
7011 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007012 }
7013 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007014 result = PyErr_SetFromWindowsErr(GetLastError());
7015#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 char *name;
7017 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007018
Victor Stinner8c62be82010-05-06 00:08:46 +00007019 errno = 0;
7020 name = getlogin();
7021 if (name == NULL) {
7022 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007023 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007024 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007025 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007026 }
7027 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007028 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007029 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007030#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007031 return result;
7032}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007033#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007034
Larry Hastings2f936352014-08-05 14:04:04 +10007035
Guido van Rossumad0ee831995-03-01 10:34:45 +00007036#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007037/*[clinic input]
7038os.getuid
7039
7040Return the current process's user id.
7041[clinic start generated code]*/
7042
Larry Hastings2f936352014-08-05 14:04:04 +10007043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007044os_getuid_impl(PyObject *module)
7045/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007046{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007047 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007048}
Larry Hastings2f936352014-08-05 14:04:04 +10007049#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007050
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007051
Brian Curtineb24d742010-04-12 17:16:38 +00007052#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007053#define HAVE_KILL
7054#endif /* MS_WINDOWS */
7055
7056#ifdef HAVE_KILL
7057/*[clinic input]
7058os.kill
7059
7060 pid: pid_t
7061 signal: Py_ssize_t
7062 /
7063
7064Kill a process with a signal.
7065[clinic start generated code]*/
7066
Larry Hastings2f936352014-08-05 14:04:04 +10007067static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007068os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7069/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007070#ifndef MS_WINDOWS
7071{
7072 if (kill(pid, (int)signal) == -1)
7073 return posix_error();
7074 Py_RETURN_NONE;
7075}
7076#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00007077{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007078 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007079 DWORD sig = (DWORD)signal;
7080 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007082
Victor Stinner8c62be82010-05-06 00:08:46 +00007083 /* Console processes which share a common console can be sent CTRL+C or
7084 CTRL+BREAK events, provided they handle said events. */
7085 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007086 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 err = GetLastError();
7088 PyErr_SetFromWindowsErr(err);
7089 }
7090 else
7091 Py_RETURN_NONE;
7092 }
Brian Curtineb24d742010-04-12 17:16:38 +00007093
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7095 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007096 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 if (handle == NULL) {
7098 err = GetLastError();
7099 return PyErr_SetFromWindowsErr(err);
7100 }
Brian Curtineb24d742010-04-12 17:16:38 +00007101
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 if (TerminateProcess(handle, sig) == 0) {
7103 err = GetLastError();
7104 result = PyErr_SetFromWindowsErr(err);
7105 } else {
7106 Py_INCREF(Py_None);
7107 result = Py_None;
7108 }
Brian Curtineb24d742010-04-12 17:16:38 +00007109
Victor Stinner8c62be82010-05-06 00:08:46 +00007110 CloseHandle(handle);
7111 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00007112}
Larry Hastings2f936352014-08-05 14:04:04 +10007113#endif /* !MS_WINDOWS */
7114#endif /* HAVE_KILL */
7115
7116
7117#ifdef HAVE_KILLPG
7118/*[clinic input]
7119os.killpg
7120
7121 pgid: pid_t
7122 signal: int
7123 /
7124
7125Kill a process group with a signal.
7126[clinic start generated code]*/
7127
Larry Hastings2f936352014-08-05 14:04:04 +10007128static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007129os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7130/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007131{
7132 /* XXX some man pages make the `pgid` parameter an int, others
7133 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7134 take the same type. Moreover, pid_t is always at least as wide as
7135 int (else compilation of this module fails), which is safe. */
7136 if (killpg(pgid, signal) == -1)
7137 return posix_error();
7138 Py_RETURN_NONE;
7139}
7140#endif /* HAVE_KILLPG */
7141
Brian Curtineb24d742010-04-12 17:16:38 +00007142
Guido van Rossumc0125471996-06-28 18:55:32 +00007143#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007144#ifdef HAVE_SYS_LOCK_H
7145#include <sys/lock.h>
7146#endif
7147
Larry Hastings2f936352014-08-05 14:04:04 +10007148/*[clinic input]
7149os.plock
7150 op: int
7151 /
7152
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007153Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007154[clinic start generated code]*/
7155
Larry Hastings2f936352014-08-05 14:04:04 +10007156static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007157os_plock_impl(PyObject *module, int op)
7158/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007159{
Victor Stinner8c62be82010-05-06 00:08:46 +00007160 if (plock(op) == -1)
7161 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007162 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007163}
Larry Hastings2f936352014-08-05 14:04:04 +10007164#endif /* HAVE_PLOCK */
7165
Guido van Rossumc0125471996-06-28 18:55:32 +00007166
Guido van Rossumb6775db1994-08-01 11:34:53 +00007167#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007168/*[clinic input]
7169os.setuid
7170
7171 uid: uid_t
7172 /
7173
7174Set the current process's user id.
7175[clinic start generated code]*/
7176
Larry Hastings2f936352014-08-05 14:04:04 +10007177static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007178os_setuid_impl(PyObject *module, uid_t uid)
7179/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007180{
Victor Stinner8c62be82010-05-06 00:08:46 +00007181 if (setuid(uid) < 0)
7182 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007183 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007184}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007185#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007186
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007187
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007188#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007189/*[clinic input]
7190os.seteuid
7191
7192 euid: uid_t
7193 /
7194
7195Set the current process's effective user id.
7196[clinic start generated code]*/
7197
Larry Hastings2f936352014-08-05 14:04:04 +10007198static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007199os_seteuid_impl(PyObject *module, uid_t euid)
7200/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007201{
7202 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007203 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007204 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007205}
7206#endif /* HAVE_SETEUID */
7207
Larry Hastings2f936352014-08-05 14:04:04 +10007208
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007209#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007210/*[clinic input]
7211os.setegid
7212
7213 egid: gid_t
7214 /
7215
7216Set the current process's effective group id.
7217[clinic start generated code]*/
7218
Larry Hastings2f936352014-08-05 14:04:04 +10007219static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007220os_setegid_impl(PyObject *module, gid_t egid)
7221/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007222{
7223 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007224 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007225 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007226}
7227#endif /* HAVE_SETEGID */
7228
Larry Hastings2f936352014-08-05 14:04:04 +10007229
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007230#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007231/*[clinic input]
7232os.setreuid
7233
7234 ruid: uid_t
7235 euid: uid_t
7236 /
7237
7238Set the current process's real and effective user ids.
7239[clinic start generated code]*/
7240
Larry Hastings2f936352014-08-05 14:04:04 +10007241static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007242os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7243/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007244{
Victor Stinner8c62be82010-05-06 00:08:46 +00007245 if (setreuid(ruid, euid) < 0) {
7246 return posix_error();
7247 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007248 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007249 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007250}
7251#endif /* HAVE_SETREUID */
7252
Larry Hastings2f936352014-08-05 14:04:04 +10007253
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007254#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007255/*[clinic input]
7256os.setregid
7257
7258 rgid: gid_t
7259 egid: gid_t
7260 /
7261
7262Set the current process's real and effective group ids.
7263[clinic start generated code]*/
7264
Larry Hastings2f936352014-08-05 14:04:04 +10007265static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007266os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7267/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007268{
7269 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007270 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007271 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007272}
7273#endif /* HAVE_SETREGID */
7274
Larry Hastings2f936352014-08-05 14:04:04 +10007275
Guido van Rossumb6775db1994-08-01 11:34:53 +00007276#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007277/*[clinic input]
7278os.setgid
7279 gid: gid_t
7280 /
7281
7282Set the current process's group id.
7283[clinic start generated code]*/
7284
Larry Hastings2f936352014-08-05 14:04:04 +10007285static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007286os_setgid_impl(PyObject *module, gid_t gid)
7287/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007288{
Victor Stinner8c62be82010-05-06 00:08:46 +00007289 if (setgid(gid) < 0)
7290 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007291 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007292}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007293#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007294
Larry Hastings2f936352014-08-05 14:04:04 +10007295
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007296#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007297/*[clinic input]
7298os.setgroups
7299
7300 groups: object
7301 /
7302
7303Set the groups of the current process to list.
7304[clinic start generated code]*/
7305
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007306static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007307os_setgroups(PyObject *module, PyObject *groups)
7308/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007309{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007310 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007311 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007312
Victor Stinner8c62be82010-05-06 00:08:46 +00007313 if (!PySequence_Check(groups)) {
7314 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7315 return NULL;
7316 }
7317 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007318 if (len < 0) {
7319 return NULL;
7320 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007321 if (len > MAX_GROUPS) {
7322 PyErr_SetString(PyExc_ValueError, "too many groups");
7323 return NULL;
7324 }
7325 for(i = 0; i < len; i++) {
7326 PyObject *elem;
7327 elem = PySequence_GetItem(groups, i);
7328 if (!elem)
7329 return NULL;
7330 if (!PyLong_Check(elem)) {
7331 PyErr_SetString(PyExc_TypeError,
7332 "groups must be integers");
7333 Py_DECREF(elem);
7334 return NULL;
7335 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007336 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007337 Py_DECREF(elem);
7338 return NULL;
7339 }
7340 }
7341 Py_DECREF(elem);
7342 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007343
Victor Stinner8c62be82010-05-06 00:08:46 +00007344 if (setgroups(len, grouplist) < 0)
7345 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007346 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007347}
7348#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007349
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007350#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7351static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007352wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007353{
Victor Stinner8c62be82010-05-06 00:08:46 +00007354 PyObject *result;
7355 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02007356 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007357
Victor Stinner8c62be82010-05-06 00:08:46 +00007358 if (pid == -1)
7359 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007360
Victor Stinner8c62be82010-05-06 00:08:46 +00007361 if (struct_rusage == NULL) {
7362 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7363 if (m == NULL)
7364 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02007365 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007366 Py_DECREF(m);
7367 if (struct_rusage == NULL)
7368 return NULL;
7369 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007370
Victor Stinner8c62be82010-05-06 00:08:46 +00007371 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7372 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
7373 if (!result)
7374 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007375
7376#ifndef doubletime
7377#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7378#endif
7379
Victor Stinner8c62be82010-05-06 00:08:46 +00007380 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007381 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007382 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007383 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007384#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007385 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7386 SET_INT(result, 2, ru->ru_maxrss);
7387 SET_INT(result, 3, ru->ru_ixrss);
7388 SET_INT(result, 4, ru->ru_idrss);
7389 SET_INT(result, 5, ru->ru_isrss);
7390 SET_INT(result, 6, ru->ru_minflt);
7391 SET_INT(result, 7, ru->ru_majflt);
7392 SET_INT(result, 8, ru->ru_nswap);
7393 SET_INT(result, 9, ru->ru_inblock);
7394 SET_INT(result, 10, ru->ru_oublock);
7395 SET_INT(result, 11, ru->ru_msgsnd);
7396 SET_INT(result, 12, ru->ru_msgrcv);
7397 SET_INT(result, 13, ru->ru_nsignals);
7398 SET_INT(result, 14, ru->ru_nvcsw);
7399 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007400#undef SET_INT
7401
Victor Stinner8c62be82010-05-06 00:08:46 +00007402 if (PyErr_Occurred()) {
7403 Py_DECREF(result);
7404 return NULL;
7405 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007406
Victor Stinner8c62be82010-05-06 00:08:46 +00007407 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007408}
7409#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7410
Larry Hastings2f936352014-08-05 14:04:04 +10007411
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007412#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007413/*[clinic input]
7414os.wait3
7415
7416 options: int
7417Wait for completion of a child process.
7418
7419Returns a tuple of information about the child process:
7420 (pid, status, rusage)
7421[clinic start generated code]*/
7422
Larry Hastings2f936352014-08-05 14:04:04 +10007423static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007424os_wait3_impl(PyObject *module, int options)
7425/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007426{
Victor Stinner8c62be82010-05-06 00:08:46 +00007427 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007428 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007429 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007430 WAIT_TYPE status;
7431 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007432
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007433 do {
7434 Py_BEGIN_ALLOW_THREADS
7435 pid = wait3(&status, options, &ru);
7436 Py_END_ALLOW_THREADS
7437 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7438 if (pid < 0)
7439 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007440
Victor Stinner4195b5c2012-02-08 23:03:19 +01007441 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007442}
7443#endif /* HAVE_WAIT3 */
7444
Larry Hastings2f936352014-08-05 14:04:04 +10007445
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007446#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007447/*[clinic input]
7448
7449os.wait4
7450
7451 pid: pid_t
7452 options: int
7453
7454Wait for completion of a specific child process.
7455
7456Returns a tuple of information about the child process:
7457 (pid, status, rusage)
7458[clinic start generated code]*/
7459
Larry Hastings2f936352014-08-05 14:04:04 +10007460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007461os_wait4_impl(PyObject *module, pid_t pid, int options)
7462/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007463{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007464 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007465 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007466 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007467 WAIT_TYPE status;
7468 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007469
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007470 do {
7471 Py_BEGIN_ALLOW_THREADS
7472 res = wait4(pid, &status, options, &ru);
7473 Py_END_ALLOW_THREADS
7474 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7475 if (res < 0)
7476 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007477
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007478 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007479}
7480#endif /* HAVE_WAIT4 */
7481
Larry Hastings2f936352014-08-05 14:04:04 +10007482
Ross Lagerwall7807c352011-03-17 20:20:30 +02007483#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007484/*[clinic input]
7485os.waitid
7486
7487 idtype: idtype_t
7488 Must be one of be P_PID, P_PGID or P_ALL.
7489 id: id_t
7490 The id to wait on.
7491 options: int
7492 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7493 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7494 /
7495
7496Returns the result of waiting for a process or processes.
7497
7498Returns either waitid_result or None if WNOHANG is specified and there are
7499no children in a waitable state.
7500[clinic start generated code]*/
7501
Larry Hastings2f936352014-08-05 14:04:04 +10007502static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007503os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7504/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007505{
7506 PyObject *result;
7507 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007508 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007509 siginfo_t si;
7510 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007511
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007512 do {
7513 Py_BEGIN_ALLOW_THREADS
7514 res = waitid(idtype, id, &si, options);
7515 Py_END_ALLOW_THREADS
7516 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7517 if (res < 0)
7518 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007519
7520 if (si.si_pid == 0)
7521 Py_RETURN_NONE;
7522
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007523 result = PyStructSequence_New(WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007524 if (!result)
7525 return NULL;
7526
7527 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007528 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007529 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7530 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7531 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7532 if (PyErr_Occurred()) {
7533 Py_DECREF(result);
7534 return NULL;
7535 }
7536
7537 return result;
7538}
Larry Hastings2f936352014-08-05 14:04:04 +10007539#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007540
Larry Hastings2f936352014-08-05 14:04:04 +10007541
7542#if defined(HAVE_WAITPID)
7543/*[clinic input]
7544os.waitpid
7545 pid: pid_t
7546 options: int
7547 /
7548
7549Wait for completion of a given child process.
7550
7551Returns a tuple of information regarding the child process:
7552 (pid, status)
7553
7554The options argument is ignored on Windows.
7555[clinic start generated code]*/
7556
Larry Hastings2f936352014-08-05 14:04:04 +10007557static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007558os_waitpid_impl(PyObject *module, pid_t pid, int options)
7559/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007560{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007561 pid_t res;
7562 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007563 WAIT_TYPE status;
7564 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007565
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007566 do {
7567 Py_BEGIN_ALLOW_THREADS
7568 res = waitpid(pid, &status, options);
7569 Py_END_ALLOW_THREADS
7570 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7571 if (res < 0)
7572 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007573
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007574 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007575}
Tim Petersab034fa2002-02-01 11:27:43 +00007576#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007577/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007578/*[clinic input]
7579os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007580 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007581 options: int
7582 /
7583
7584Wait for completion of a given process.
7585
7586Returns a tuple of information regarding the process:
7587 (pid, status << 8)
7588
7589The options argument is ignored on Windows.
7590[clinic start generated code]*/
7591
Larry Hastings2f936352014-08-05 14:04:04 +10007592static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007593os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007594/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007595{
7596 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007597 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007598 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007599
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007600 do {
7601 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007602 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007603 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007604 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007605 Py_END_ALLOW_THREADS
7606 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007607 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007608 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007609
Victor Stinner8c62be82010-05-06 00:08:46 +00007610 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007611 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007612}
Larry Hastings2f936352014-08-05 14:04:04 +10007613#endif
7614
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007615
Guido van Rossumad0ee831995-03-01 10:34:45 +00007616#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007617/*[clinic input]
7618os.wait
7619
7620Wait for completion of a child process.
7621
7622Returns a tuple of information about the child process:
7623 (pid, status)
7624[clinic start generated code]*/
7625
Larry Hastings2f936352014-08-05 14:04:04 +10007626static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007627os_wait_impl(PyObject *module)
7628/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007629{
Victor Stinner8c62be82010-05-06 00:08:46 +00007630 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007631 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007632 WAIT_TYPE status;
7633 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007634
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007635 do {
7636 Py_BEGIN_ALLOW_THREADS
7637 pid = wait(&status);
7638 Py_END_ALLOW_THREADS
7639 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7640 if (pid < 0)
7641 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007642
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007644}
Larry Hastings2f936352014-08-05 14:04:04 +10007645#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007646
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007647
Larry Hastings9cf065c2012-06-22 16:30:09 -07007648#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007649/*[clinic input]
7650os.readlink
7651
7652 path: path_t
7653 *
7654 dir_fd: dir_fd(requires='readlinkat') = None
7655
7656Return a string representing the path to which the symbolic link points.
7657
7658If dir_fd is not None, it should be a file descriptor open to a directory,
7659and path should be relative; path will then be relative to that directory.
7660
7661dir_fd may not be implemented on your platform. If it is unavailable,
7662using it will raise a NotImplementedError.
7663[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007664
Barry Warsaw53699e91996-12-10 23:23:01 +00007665static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007666os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
7667/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007668{
Berker Peksage0b5b202018-08-15 13:03:41 +03007669#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007670 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007671 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007672
7673 Py_BEGIN_ALLOW_THREADS
7674#ifdef HAVE_READLINKAT
7675 if (dir_fd != DEFAULT_DIR_FD)
7676 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
7677 else
7678#endif
7679 length = readlink(path->narrow, buffer, MAXPATHLEN);
7680 Py_END_ALLOW_THREADS
7681
7682 if (length < 0) {
7683 return path_error(path);
7684 }
7685 buffer[length] = '\0';
7686
7687 if (PyUnicode_Check(path->object))
7688 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7689 else
7690 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03007691#elif defined(MS_WINDOWS)
7692 DWORD n_bytes_returned;
7693 DWORD io_result;
7694 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03007695 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7696 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
7697 const wchar_t *print_name;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007698 PyObject *result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007699
Larry Hastings2f936352014-08-05 14:04:04 +10007700 /* First get a handle to the reparse point */
7701 Py_BEGIN_ALLOW_THREADS
7702 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007703 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10007704 0,
7705 0,
7706 0,
7707 OPEN_EXISTING,
7708 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7709 0);
7710 Py_END_ALLOW_THREADS
7711
Berker Peksage0b5b202018-08-15 13:03:41 +03007712 if (reparse_point_handle == INVALID_HANDLE_VALUE) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007713 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007714 }
Larry Hastings2f936352014-08-05 14:04:04 +10007715
7716 Py_BEGIN_ALLOW_THREADS
7717 /* New call DeviceIoControl to read the reparse point */
7718 io_result = DeviceIoControl(
7719 reparse_point_handle,
7720 FSCTL_GET_REPARSE_POINT,
7721 0, 0, /* in buffer */
7722 target_buffer, sizeof(target_buffer),
7723 &n_bytes_returned,
7724 0 /* we're not using OVERLAPPED_IO */
7725 );
7726 CloseHandle(reparse_point_handle);
7727 Py_END_ALLOW_THREADS
7728
Berker Peksage0b5b202018-08-15 13:03:41 +03007729 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007730 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03007731 }
Larry Hastings2f936352014-08-05 14:04:04 +10007732
7733 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7734 {
7735 PyErr_SetString(PyExc_ValueError,
7736 "not a symbolic link");
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007737 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10007738 }
SSE43c34aad2018-02-13 00:10:35 +07007739 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7740 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007741
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007742 result = PyUnicode_FromWideChar(print_name,
7743 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
7744 if (path->narrow) {
7745 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Berker Peksage0b5b202018-08-15 13:03:41 +03007746 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03007747 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03007748#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007749}
Berker Peksage0b5b202018-08-15 13:03:41 +03007750#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007751
Larry Hastings9cf065c2012-06-22 16:30:09 -07007752#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007753
7754#if defined(MS_WINDOWS)
7755
Steve Dower6921e732018-03-05 14:26:08 -08007756/* Remove the last portion of the path - return 0 on success */
7757static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007758_dirnameW(WCHAR *path)
7759{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007760 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08007761 size_t length = wcsnlen_s(path, MAX_PATH);
7762 if (length == MAX_PATH) {
7763 return -1;
7764 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007765
7766 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08007767 for(ptr = path + length; ptr != path; ptr--) {
7768 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007769 break;
Steve Dower6921e732018-03-05 14:26:08 -08007770 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007771 }
7772 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08007773 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007774}
7775
Victor Stinner31b3b922013-06-05 01:49:17 +02007776/* Is this path absolute? */
7777static int
7778_is_absW(const WCHAR *path)
7779{
Steve Dower6921e732018-03-05 14:26:08 -08007780 return path[0] == L'\\' || path[0] == L'/' ||
7781 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007782}
7783
Steve Dower6921e732018-03-05 14:26:08 -08007784/* join root and rest with a backslash - return 0 on success */
7785static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007786_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7787{
Victor Stinner31b3b922013-06-05 01:49:17 +02007788 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08007789 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007790 }
7791
Steve Dower6921e732018-03-05 14:26:08 -08007792 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7793 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007794 }
Steve Dower6921e732018-03-05 14:26:08 -08007795
7796 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7797 return -1;
7798 }
7799
7800 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007801}
7802
Victor Stinner31b3b922013-06-05 01:49:17 +02007803/* Return True if the path at src relative to dest is a directory */
7804static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007805_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007806{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007807 WIN32_FILE_ATTRIBUTE_DATA src_info;
7808 WCHAR dest_parent[MAX_PATH];
7809 WCHAR src_resolved[MAX_PATH] = L"";
7810
7811 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08007812 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7813 _dirnameW(dest_parent)) {
7814 return 0;
7815 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007816 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08007817 if (_joinW(src_resolved, dest_parent, src)) {
7818 return 0;
7819 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007820 return (
7821 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7822 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7823 );
7824}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007825#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007826
Larry Hastings2f936352014-08-05 14:04:04 +10007827
7828/*[clinic input]
7829os.symlink
7830 src: path_t
7831 dst: path_t
7832 target_is_directory: bool = False
7833 *
7834 dir_fd: dir_fd(requires='symlinkat')=None
7835
7836# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7837
7838Create a symbolic link pointing to src named dst.
7839
7840target_is_directory is required on Windows if the target is to be
7841 interpreted as a directory. (On Windows, symlink requires
7842 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7843 target_is_directory is ignored on non-Windows platforms.
7844
7845If dir_fd is not None, it should be a file descriptor open to a directory,
7846 and path should be relative; path will then be relative to that directory.
7847dir_fd may not be implemented on your platform.
7848 If it is unavailable, using it will raise a NotImplementedError.
7849
7850[clinic start generated code]*/
7851
Larry Hastings2f936352014-08-05 14:04:04 +10007852static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007853os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007854 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007855/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007856{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007857#ifdef MS_WINDOWS
7858 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007859 DWORD flags = 0;
7860
7861 /* Assumed true, set to false if detected to not be available. */
7862 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007863#else
7864 int result;
7865#endif
7866
Larry Hastings9cf065c2012-06-22 16:30:09 -07007867#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007868
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007869 if (windows_has_symlink_unprivileged_flag) {
7870 /* Allow non-admin symlinks if system allows it. */
7871 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
7872 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007873
Larry Hastings9cf065c2012-06-22 16:30:09 -07007874 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08007875 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007876 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
7877 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
7878 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
7879 }
7880
7881 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08007882 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007883 Py_END_ALLOW_THREADS
7884
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02007885 if (windows_has_symlink_unprivileged_flag && !result &&
7886 ERROR_INVALID_PARAMETER == GetLastError()) {
7887
7888 Py_BEGIN_ALLOW_THREADS
7889 _Py_BEGIN_SUPPRESS_IPH
7890 /* This error might be caused by
7891 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
7892 Try again, and update windows_has_symlink_unprivileged_flag if we
7893 are successful this time.
7894
7895 NOTE: There is a risk of a race condition here if there are other
7896 conditions than the flag causing ERROR_INVALID_PARAMETER, and
7897 another process (or thread) changes that condition in between our
7898 calls to CreateSymbolicLink.
7899 */
7900 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
7901 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
7902 _Py_END_SUPPRESS_IPH
7903 Py_END_ALLOW_THREADS
7904
7905 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
7906 windows_has_symlink_unprivileged_flag = FALSE;
7907 }
7908 }
7909
Larry Hastings2f936352014-08-05 14:04:04 +10007910 if (!result)
7911 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007912
7913#else
7914
Steve Dower6921e732018-03-05 14:26:08 -08007915 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7916 PyErr_SetString(PyExc_ValueError,
7917 "symlink: src and dst must be the same type");
7918 return NULL;
7919 }
7920
Larry Hastings9cf065c2012-06-22 16:30:09 -07007921 Py_BEGIN_ALLOW_THREADS
7922#if HAVE_SYMLINKAT
7923 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007924 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007925 else
7926#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007927 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007928 Py_END_ALLOW_THREADS
7929
Larry Hastings2f936352014-08-05 14:04:04 +10007930 if (result)
7931 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007932#endif
7933
Larry Hastings2f936352014-08-05 14:04:04 +10007934 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007935}
7936#endif /* HAVE_SYMLINK */
7937
Larry Hastings9cf065c2012-06-22 16:30:09 -07007938
Brian Curtind40e6f72010-07-08 21:39:08 +00007939
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007940
Larry Hastings605a62d2012-06-24 04:33:36 -07007941static PyStructSequence_Field times_result_fields[] = {
7942 {"user", "user time"},
7943 {"system", "system time"},
7944 {"children_user", "user time of children"},
7945 {"children_system", "system time of children"},
7946 {"elapsed", "elapsed time since an arbitrary point in the past"},
7947 {NULL}
7948};
7949
7950PyDoc_STRVAR(times_result__doc__,
7951"times_result: Result from os.times().\n\n\
7952This object may be accessed either as a tuple of\n\
7953 (user, system, children_user, children_system, elapsed),\n\
7954or via the attributes user, system, children_user, children_system,\n\
7955and elapsed.\n\
7956\n\
7957See os.times for more information.");
7958
7959static PyStructSequence_Desc times_result_desc = {
7960 "times_result", /* name */
7961 times_result__doc__, /* doc */
7962 times_result_fields,
7963 5
7964};
7965
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007966static PyTypeObject* TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -07007967
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007968#ifdef MS_WINDOWS
7969#define HAVE_TIMES /* mandatory, for the method table */
7970#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007971
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007972#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007973
7974static PyObject *
7975build_times_result(double user, double system,
7976 double children_user, double children_system,
7977 double elapsed)
7978{
Eddie Elizondo474eedf2018-11-13 04:09:31 -08007979 PyObject *value = PyStructSequence_New(TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07007980 if (value == NULL)
7981 return NULL;
7982
7983#define SET(i, field) \
7984 { \
7985 PyObject *o = PyFloat_FromDouble(field); \
7986 if (!o) { \
7987 Py_DECREF(value); \
7988 return NULL; \
7989 } \
7990 PyStructSequence_SET_ITEM(value, i, o); \
7991 } \
7992
7993 SET(0, user);
7994 SET(1, system);
7995 SET(2, children_user);
7996 SET(3, children_system);
7997 SET(4, elapsed);
7998
7999#undef SET
8000
8001 return value;
8002}
8003
Larry Hastings605a62d2012-06-24 04:33:36 -07008004
Larry Hastings2f936352014-08-05 14:04:04 +10008005#ifndef MS_WINDOWS
8006#define NEED_TICKS_PER_SECOND
8007static long ticks_per_second = -1;
8008#endif /* MS_WINDOWS */
8009
8010/*[clinic input]
8011os.times
8012
8013Return a collection containing process timing information.
8014
8015The object returned behaves like a named tuple with these fields:
8016 (utime, stime, cutime, cstime, elapsed_time)
8017All fields are floating point numbers.
8018[clinic start generated code]*/
8019
Larry Hastings2f936352014-08-05 14:04:04 +10008020static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008021os_times_impl(PyObject *module)
8022/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008023#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008024{
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 FILETIME create, exit, kernel, user;
8026 HANDLE hProc;
8027 hProc = GetCurrentProcess();
8028 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8029 /* The fields of a FILETIME structure are the hi and lo part
8030 of a 64-bit value expressed in 100 nanosecond units.
8031 1e7 is one second in such units; 1e-7 the inverse.
8032 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8033 */
Larry Hastings605a62d2012-06-24 04:33:36 -07008034 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00008035 (double)(user.dwHighDateTime*429.4967296 +
8036 user.dwLowDateTime*1e-7),
8037 (double)(kernel.dwHighDateTime*429.4967296 +
8038 kernel.dwLowDateTime*1e-7),
8039 (double)0,
8040 (double)0,
8041 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008042}
Larry Hastings2f936352014-08-05 14:04:04 +10008043#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008044{
Larry Hastings2f936352014-08-05 14:04:04 +10008045
8046
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008047 struct tms t;
8048 clock_t c;
8049 errno = 0;
8050 c = times(&t);
8051 if (c == (clock_t) -1)
8052 return posix_error();
8053 return build_times_result(
8054 (double)t.tms_utime / ticks_per_second,
8055 (double)t.tms_stime / ticks_per_second,
8056 (double)t.tms_cutime / ticks_per_second,
8057 (double)t.tms_cstime / ticks_per_second,
8058 (double)c / ticks_per_second);
8059}
Larry Hastings2f936352014-08-05 14:04:04 +10008060#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008061#endif /* HAVE_TIMES */
8062
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008063
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008064#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008065/*[clinic input]
8066os.getsid
8067
8068 pid: pid_t
8069 /
8070
8071Call the system call getsid(pid) and return the result.
8072[clinic start generated code]*/
8073
Larry Hastings2f936352014-08-05 14:04:04 +10008074static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008075os_getsid_impl(PyObject *module, pid_t pid)
8076/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008077{
Victor Stinner8c62be82010-05-06 00:08:46 +00008078 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008079 sid = getsid(pid);
8080 if (sid < 0)
8081 return posix_error();
8082 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008083}
8084#endif /* HAVE_GETSID */
8085
8086
Guido van Rossumb6775db1994-08-01 11:34:53 +00008087#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008088/*[clinic input]
8089os.setsid
8090
8091Call the system call setsid().
8092[clinic start generated code]*/
8093
Larry Hastings2f936352014-08-05 14:04:04 +10008094static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008095os_setsid_impl(PyObject *module)
8096/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008097{
Victor Stinner8c62be82010-05-06 00:08:46 +00008098 if (setsid() < 0)
8099 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008100 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008101}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008102#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008103
Larry Hastings2f936352014-08-05 14:04:04 +10008104
Guido van Rossumb6775db1994-08-01 11:34:53 +00008105#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008106/*[clinic input]
8107os.setpgid
8108
8109 pid: pid_t
8110 pgrp: pid_t
8111 /
8112
8113Call the system call setpgid(pid, pgrp).
8114[clinic start generated code]*/
8115
Larry Hastings2f936352014-08-05 14:04:04 +10008116static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008117os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8118/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008119{
Victor Stinner8c62be82010-05-06 00:08:46 +00008120 if (setpgid(pid, pgrp) < 0)
8121 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008122 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008123}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008124#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008125
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008126
Guido van Rossumb6775db1994-08-01 11:34:53 +00008127#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008128/*[clinic input]
8129os.tcgetpgrp
8130
8131 fd: int
8132 /
8133
8134Return the process group associated with the terminal specified by fd.
8135[clinic start generated code]*/
8136
Larry Hastings2f936352014-08-05 14:04:04 +10008137static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008138os_tcgetpgrp_impl(PyObject *module, int fd)
8139/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008140{
8141 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 if (pgid < 0)
8143 return posix_error();
8144 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008145}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008146#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008147
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008148
Guido van Rossumb6775db1994-08-01 11:34:53 +00008149#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008150/*[clinic input]
8151os.tcsetpgrp
8152
8153 fd: int
8154 pgid: pid_t
8155 /
8156
8157Set the process group associated with the terminal specified by fd.
8158[clinic start generated code]*/
8159
Larry Hastings2f936352014-08-05 14:04:04 +10008160static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008161os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8162/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008163{
Victor Stinner8c62be82010-05-06 00:08:46 +00008164 if (tcsetpgrp(fd, pgid) < 0)
8165 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008166 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008167}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008168#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008169
Guido van Rossum687dd131993-05-17 08:34:16 +00008170/* Functions acting on file descriptors */
8171
Victor Stinnerdaf45552013-08-28 00:53:59 +02008172#ifdef O_CLOEXEC
8173extern int _Py_open_cloexec_works;
8174#endif
8175
Larry Hastings2f936352014-08-05 14:04:04 +10008176
8177/*[clinic input]
8178os.open -> int
8179 path: path_t
8180 flags: int
8181 mode: int = 0o777
8182 *
8183 dir_fd: dir_fd(requires='openat') = None
8184
8185# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8186
8187Open a file for low level IO. Returns a file descriptor (integer).
8188
8189If dir_fd is not None, it should be a file descriptor open to a directory,
8190 and path should be relative; path will then be relative to that directory.
8191dir_fd may not be implemented on your platform.
8192 If it is unavailable, using it will raise a NotImplementedError.
8193[clinic start generated code]*/
8194
Larry Hastings2f936352014-08-05 14:04:04 +10008195static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008196os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8197/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008198{
8199 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008200 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008201
Victor Stinnerdaf45552013-08-28 00:53:59 +02008202#ifdef O_CLOEXEC
8203 int *atomic_flag_works = &_Py_open_cloexec_works;
8204#elif !defined(MS_WINDOWS)
8205 int *atomic_flag_works = NULL;
8206#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008207
Victor Stinnerdaf45552013-08-28 00:53:59 +02008208#ifdef MS_WINDOWS
8209 flags |= O_NOINHERIT;
8210#elif defined(O_CLOEXEC)
8211 flags |= O_CLOEXEC;
8212#endif
8213
Steve Dower8fc89802015-04-12 00:26:27 -04008214 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008215 do {
8216 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008217#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008218 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008219#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008220#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008221 if (dir_fd != DEFAULT_DIR_FD)
8222 fd = openat(dir_fd, path->narrow, flags, mode);
8223 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008224#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008225 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008226#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008227 Py_END_ALLOW_THREADS
8228 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008229 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008230
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008231 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008232 if (!async_err)
8233 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008234 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008235 }
8236
Victor Stinnerdaf45552013-08-28 00:53:59 +02008237#ifndef MS_WINDOWS
8238 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8239 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008240 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008241 }
8242#endif
8243
Larry Hastings2f936352014-08-05 14:04:04 +10008244 return fd;
8245}
8246
8247
8248/*[clinic input]
8249os.close
8250
8251 fd: int
8252
8253Close a file descriptor.
8254[clinic start generated code]*/
8255
Barry Warsaw53699e91996-12-10 23:23:01 +00008256static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008257os_close_impl(PyObject *module, int fd)
8258/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008259{
Larry Hastings2f936352014-08-05 14:04:04 +10008260 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008261 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8262 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8263 * for more details.
8264 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008265 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008266 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008267 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008268 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008269 Py_END_ALLOW_THREADS
8270 if (res < 0)
8271 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008272 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008273}
8274
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008275
Larry Hastings2f936352014-08-05 14:04:04 +10008276/*[clinic input]
8277os.closerange
8278
8279 fd_low: int
8280 fd_high: int
8281 /
8282
8283Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8284[clinic start generated code]*/
8285
Larry Hastings2f936352014-08-05 14:04:04 +10008286static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008287os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8288/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008289{
8290 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00008291 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008292 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07008293 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07008294 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04008295 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 Py_END_ALLOW_THREADS
8297 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008298}
8299
8300
Larry Hastings2f936352014-08-05 14:04:04 +10008301/*[clinic input]
8302os.dup -> int
8303
8304 fd: int
8305 /
8306
8307Return a duplicate of a file descriptor.
8308[clinic start generated code]*/
8309
Larry Hastings2f936352014-08-05 14:04:04 +10008310static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008311os_dup_impl(PyObject *module, int fd)
8312/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008313{
8314 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008315}
8316
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008317
Larry Hastings2f936352014-08-05 14:04:04 +10008318/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008319os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008320 fd: int
8321 fd2: int
8322 inheritable: bool=True
8323
8324Duplicate file descriptor.
8325[clinic start generated code]*/
8326
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008327static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008328os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008329/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008330{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008331 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008332#if defined(HAVE_DUP3) && \
8333 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8334 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008335 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008336#endif
8337
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008338 if (fd < 0 || fd2 < 0) {
8339 posix_error();
8340 return -1;
8341 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008342
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008343 /* dup2() can fail with EINTR if the target FD is already open, because it
8344 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8345 * upon close(), and therefore below.
8346 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008347#ifdef MS_WINDOWS
8348 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008349 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008350 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008351 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008352 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008353 if (res < 0) {
8354 posix_error();
8355 return -1;
8356 }
8357 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008358
8359 /* Character files like console cannot be make non-inheritable */
8360 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8361 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008362 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008363 }
8364
8365#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8366 Py_BEGIN_ALLOW_THREADS
8367 if (!inheritable)
8368 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8369 else
8370 res = dup2(fd, fd2);
8371 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008372 if (res < 0) {
8373 posix_error();
8374 return -1;
8375 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008376
8377#else
8378
8379#ifdef HAVE_DUP3
8380 if (!inheritable && dup3_works != 0) {
8381 Py_BEGIN_ALLOW_THREADS
8382 res = dup3(fd, fd2, O_CLOEXEC);
8383 Py_END_ALLOW_THREADS
8384 if (res < 0) {
8385 if (dup3_works == -1)
8386 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008387 if (dup3_works) {
8388 posix_error();
8389 return -1;
8390 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008391 }
8392 }
8393
8394 if (inheritable || dup3_works == 0)
8395 {
8396#endif
8397 Py_BEGIN_ALLOW_THREADS
8398 res = dup2(fd, fd2);
8399 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008400 if (res < 0) {
8401 posix_error();
8402 return -1;
8403 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008404
8405 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8406 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008407 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008408 }
8409#ifdef HAVE_DUP3
8410 }
8411#endif
8412
8413#endif
8414
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008415 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008416}
8417
Larry Hastings2f936352014-08-05 14:04:04 +10008418
Ross Lagerwall7807c352011-03-17 20:20:30 +02008419#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008420/*[clinic input]
8421os.lockf
8422
8423 fd: int
8424 An open file descriptor.
8425 command: int
8426 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8427 length: Py_off_t
8428 The number of bytes to lock, starting at the current position.
8429 /
8430
8431Apply, test or remove a POSIX lock on an open file descriptor.
8432
8433[clinic start generated code]*/
8434
Larry Hastings2f936352014-08-05 14:04:04 +10008435static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008436os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8437/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008438{
8439 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008440
8441 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008442 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008443 Py_END_ALLOW_THREADS
8444
8445 if (res < 0)
8446 return posix_error();
8447
8448 Py_RETURN_NONE;
8449}
Larry Hastings2f936352014-08-05 14:04:04 +10008450#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008451
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008452
Larry Hastings2f936352014-08-05 14:04:04 +10008453/*[clinic input]
8454os.lseek -> Py_off_t
8455
8456 fd: int
8457 position: Py_off_t
8458 how: int
8459 /
8460
8461Set the position of a file descriptor. Return the new position.
8462
8463Return the new cursor position in number of bytes
8464relative to the beginning of the file.
8465[clinic start generated code]*/
8466
Larry Hastings2f936352014-08-05 14:04:04 +10008467static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008468os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8469/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008470{
8471 Py_off_t result;
8472
Guido van Rossum687dd131993-05-17 08:34:16 +00008473#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008474 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8475 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008476 case 0: how = SEEK_SET; break;
8477 case 1: how = SEEK_CUR; break;
8478 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008479 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008480#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008481
Victor Stinner8c62be82010-05-06 00:08:46 +00008482 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008483 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008484#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008485 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008486#else
Larry Hastings2f936352014-08-05 14:04:04 +10008487 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008488#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008489 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008490 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008491 if (result < 0)
8492 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008493
Larry Hastings2f936352014-08-05 14:04:04 +10008494 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008495}
8496
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008497
Larry Hastings2f936352014-08-05 14:04:04 +10008498/*[clinic input]
8499os.read
8500 fd: int
8501 length: Py_ssize_t
8502 /
8503
8504Read from a file descriptor. Returns a bytes object.
8505[clinic start generated code]*/
8506
Larry Hastings2f936352014-08-05 14:04:04 +10008507static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008508os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8509/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008510{
Victor Stinner8c62be82010-05-06 00:08:46 +00008511 Py_ssize_t n;
8512 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008513
8514 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008515 errno = EINVAL;
8516 return posix_error();
8517 }
Larry Hastings2f936352014-08-05 14:04:04 +10008518
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008519 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008520
8521 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008522 if (buffer == NULL)
8523 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008524
Victor Stinner66aab0c2015-03-19 22:53:20 +01008525 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8526 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008527 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008528 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008529 }
Larry Hastings2f936352014-08-05 14:04:04 +10008530
8531 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008532 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008533
Victor Stinner8c62be82010-05-06 00:08:46 +00008534 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008535}
8536
Ross Lagerwall7807c352011-03-17 20:20:30 +02008537#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008538 || defined(__APPLE__))) \
8539 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8540 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8541static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008542iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008543{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008544 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008545
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008546 *iov = PyMem_New(struct iovec, cnt);
8547 if (*iov == NULL) {
8548 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008549 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008550 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008551
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008552 *buf = PyMem_New(Py_buffer, cnt);
8553 if (*buf == NULL) {
8554 PyMem_Del(*iov);
8555 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008556 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008557 }
8558
8559 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008560 PyObject *item = PySequence_GetItem(seq, i);
8561 if (item == NULL)
8562 goto fail;
8563 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8564 Py_DECREF(item);
8565 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008566 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008567 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008568 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008569 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008570 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008571 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008572
8573fail:
8574 PyMem_Del(*iov);
8575 for (j = 0; j < i; j++) {
8576 PyBuffer_Release(&(*buf)[j]);
8577 }
8578 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008579 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008580}
8581
8582static void
8583iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8584{
8585 int i;
8586 PyMem_Del(iov);
8587 for (i = 0; i < cnt; i++) {
8588 PyBuffer_Release(&buf[i]);
8589 }
8590 PyMem_Del(buf);
8591}
8592#endif
8593
Larry Hastings2f936352014-08-05 14:04:04 +10008594
Ross Lagerwall7807c352011-03-17 20:20:30 +02008595#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008596/*[clinic input]
8597os.readv -> Py_ssize_t
8598
8599 fd: int
8600 buffers: object
8601 /
8602
8603Read from a file descriptor fd into an iterable of buffers.
8604
8605The buffers should be mutable buffers accepting bytes.
8606readv will transfer data into each buffer until it is full
8607and then move on to the next buffer in the sequence to hold
8608the rest of the data.
8609
8610readv returns the total number of bytes read,
8611which may be less than the total capacity of all the buffers.
8612[clinic start generated code]*/
8613
Larry Hastings2f936352014-08-05 14:04:04 +10008614static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008615os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8616/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008617{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008618 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008619 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008620 struct iovec *iov;
8621 Py_buffer *buf;
8622
Larry Hastings2f936352014-08-05 14:04:04 +10008623 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008624 PyErr_SetString(PyExc_TypeError,
8625 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008626 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008627 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008628
Larry Hastings2f936352014-08-05 14:04:04 +10008629 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008630 if (cnt < 0)
8631 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008632
8633 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8634 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008635
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008636 do {
8637 Py_BEGIN_ALLOW_THREADS
8638 n = readv(fd, iov, cnt);
8639 Py_END_ALLOW_THREADS
8640 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008641
8642 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008643 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008644 if (!async_err)
8645 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008646 return -1;
8647 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008648
Larry Hastings2f936352014-08-05 14:04:04 +10008649 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008650}
Larry Hastings2f936352014-08-05 14:04:04 +10008651#endif /* HAVE_READV */
8652
Ross Lagerwall7807c352011-03-17 20:20:30 +02008653
8654#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008655/*[clinic input]
8656# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8657os.pread
8658
8659 fd: int
8660 length: int
8661 offset: Py_off_t
8662 /
8663
8664Read a number of bytes from a file descriptor starting at a particular offset.
8665
8666Read length bytes from file descriptor fd, starting at offset bytes from
8667the beginning of the file. The file offset remains unchanged.
8668[clinic start generated code]*/
8669
Larry Hastings2f936352014-08-05 14:04:04 +10008670static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008671os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8672/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008673{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008674 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008675 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008676 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008677
Larry Hastings2f936352014-08-05 14:04:04 +10008678 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008679 errno = EINVAL;
8680 return posix_error();
8681 }
Larry Hastings2f936352014-08-05 14:04:04 +10008682 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008683 if (buffer == NULL)
8684 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008685
8686 do {
8687 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008688 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008689 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008690 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008691 Py_END_ALLOW_THREADS
8692 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8693
Ross Lagerwall7807c352011-03-17 20:20:30 +02008694 if (n < 0) {
8695 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008696 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008697 }
Larry Hastings2f936352014-08-05 14:04:04 +10008698 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008699 _PyBytes_Resize(&buffer, n);
8700 return buffer;
8701}
Larry Hastings2f936352014-08-05 14:04:04 +10008702#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008703
Pablo Galindo4defba32018-01-27 16:16:37 +00008704#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8705/*[clinic input]
8706os.preadv -> Py_ssize_t
8707
8708 fd: int
8709 buffers: object
8710 offset: Py_off_t
8711 flags: int = 0
8712 /
8713
8714Reads from a file descriptor into a number of mutable bytes-like objects.
8715
8716Combines the functionality of readv() and pread(). As readv(), it will
8717transfer data into each buffer until it is full and then move on to the next
8718buffer in the sequence to hold the rest of the data. Its fourth argument,
8719specifies the file offset at which the input operation is to be performed. It
8720will return the total number of bytes read (which can be less than the total
8721capacity of all the objects).
8722
8723The flags argument contains a bitwise OR of zero or more of the following flags:
8724
8725- RWF_HIPRI
8726- RWF_NOWAIT
8727
8728Using non-zero flags requires Linux 4.6 or newer.
8729[clinic start generated code]*/
8730
8731static Py_ssize_t
8732os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8733 int flags)
8734/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8735{
8736 Py_ssize_t cnt, n;
8737 int async_err = 0;
8738 struct iovec *iov;
8739 Py_buffer *buf;
8740
8741 if (!PySequence_Check(buffers)) {
8742 PyErr_SetString(PyExc_TypeError,
8743 "preadv2() arg 2 must be a sequence");
8744 return -1;
8745 }
8746
8747 cnt = PySequence_Size(buffers);
8748 if (cnt < 0) {
8749 return -1;
8750 }
8751
8752#ifndef HAVE_PREADV2
8753 if(flags != 0) {
8754 argument_unavailable_error("preadv2", "flags");
8755 return -1;
8756 }
8757#endif
8758
8759 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8760 return -1;
8761 }
8762#ifdef HAVE_PREADV2
8763 do {
8764 Py_BEGIN_ALLOW_THREADS
8765 _Py_BEGIN_SUPPRESS_IPH
8766 n = preadv2(fd, iov, cnt, offset, flags);
8767 _Py_END_SUPPRESS_IPH
8768 Py_END_ALLOW_THREADS
8769 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8770#else
8771 do {
8772 Py_BEGIN_ALLOW_THREADS
8773 _Py_BEGIN_SUPPRESS_IPH
8774 n = preadv(fd, iov, cnt, offset);
8775 _Py_END_SUPPRESS_IPH
8776 Py_END_ALLOW_THREADS
8777 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8778#endif
8779
8780 iov_cleanup(iov, buf, cnt);
8781 if (n < 0) {
8782 if (!async_err) {
8783 posix_error();
8784 }
8785 return -1;
8786 }
8787
8788 return n;
8789}
8790#endif /* HAVE_PREADV */
8791
Larry Hastings2f936352014-08-05 14:04:04 +10008792
8793/*[clinic input]
8794os.write -> Py_ssize_t
8795
8796 fd: int
8797 data: Py_buffer
8798 /
8799
8800Write a bytes object to a file descriptor.
8801[clinic start generated code]*/
8802
Larry Hastings2f936352014-08-05 14:04:04 +10008803static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008804os_write_impl(PyObject *module, int fd, Py_buffer *data)
8805/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008806{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008807 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008808}
8809
8810#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008811PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008812"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008813sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008814 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008815Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008816
Larry Hastings2f936352014-08-05 14:04:04 +10008817/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008818static PyObject *
8819posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8820{
8821 int in, out;
8822 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008823 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008824 off_t offset;
8825
8826#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8827#ifndef __APPLE__
8828 Py_ssize_t len;
8829#endif
8830 PyObject *headers = NULL, *trailers = NULL;
8831 Py_buffer *hbuf, *tbuf;
8832 off_t sbytes;
8833 struct sf_hdtr sf;
8834 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008835 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008836 static char *keywords[] = {"out", "in",
8837 "offset", "count",
8838 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008839
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008840 sf.headers = NULL;
8841 sf.trailers = NULL;
8842
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008843#ifdef __APPLE__
8844 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008845 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008846#else
8847 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008848 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008849#endif
8850 &headers, &trailers, &flags))
8851 return NULL;
8852 if (headers != NULL) {
8853 if (!PySequence_Check(headers)) {
8854 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008855 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008856 return NULL;
8857 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008858 Py_ssize_t i = PySequence_Size(headers);
8859 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008860 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008861 if (i > INT_MAX) {
8862 PyErr_SetString(PyExc_OverflowError,
8863 "sendfile() header is too large");
8864 return NULL;
8865 }
8866 if (i > 0) {
8867 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008868 if (iov_setup(&(sf.headers), &hbuf,
8869 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008870 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008871#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008872 for (i = 0; i < sf.hdr_cnt; i++) {
8873 Py_ssize_t blen = sf.headers[i].iov_len;
8874# define OFF_T_MAX 0x7fffffffffffffff
8875 if (sbytes >= OFF_T_MAX - blen) {
8876 PyErr_SetString(PyExc_OverflowError,
8877 "sendfile() header is too large");
8878 return NULL;
8879 }
8880 sbytes += blen;
8881 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008882#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008883 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008884 }
8885 }
8886 if (trailers != NULL) {
8887 if (!PySequence_Check(trailers)) {
8888 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008889 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008890 return NULL;
8891 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008892 Py_ssize_t i = PySequence_Size(trailers);
8893 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008894 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008895 if (i > INT_MAX) {
8896 PyErr_SetString(PyExc_OverflowError,
8897 "sendfile() trailer is too large");
8898 return NULL;
8899 }
8900 if (i > 0) {
8901 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008902 if (iov_setup(&(sf.trailers), &tbuf,
8903 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008904 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008905 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008906 }
8907 }
8908
Steve Dower8fc89802015-04-12 00:26:27 -04008909 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008910 do {
8911 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008912#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008913 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008914#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008915 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008916#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008917 Py_END_ALLOW_THREADS
8918 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008919 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008920
8921 if (sf.headers != NULL)
8922 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8923 if (sf.trailers != NULL)
8924 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8925
8926 if (ret < 0) {
8927 if ((errno == EAGAIN) || (errno == EBUSY)) {
8928 if (sbytes != 0) {
8929 // some data has been sent
8930 goto done;
8931 }
8932 else {
8933 // no data has been sent; upper application is supposed
8934 // to retry on EAGAIN or EBUSY
8935 return posix_error();
8936 }
8937 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008938 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008939 }
8940 goto done;
8941
8942done:
8943 #if !defined(HAVE_LARGEFILE_SUPPORT)
8944 return Py_BuildValue("l", sbytes);
8945 #else
8946 return Py_BuildValue("L", sbytes);
8947 #endif
8948
8949#else
8950 Py_ssize_t count;
8951 PyObject *offobj;
8952 static char *keywords[] = {"out", "in",
8953 "offset", "count", NULL};
8954 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8955 keywords, &out, &in, &offobj, &count))
8956 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008957#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008958 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008959 do {
8960 Py_BEGIN_ALLOW_THREADS
8961 ret = sendfile(out, in, NULL, count);
8962 Py_END_ALLOW_THREADS
8963 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008964 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008965 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008966 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008967 }
8968#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008969 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008970 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008971
8972 do {
8973 Py_BEGIN_ALLOW_THREADS
8974 ret = sendfile(out, in, &offset, count);
8975 Py_END_ALLOW_THREADS
8976 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008977 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008978 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008979 return Py_BuildValue("n", ret);
8980#endif
8981}
Larry Hastings2f936352014-08-05 14:04:04 +10008982#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008983
Larry Hastings2f936352014-08-05 14:04:04 +10008984
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008985#if defined(__APPLE__)
8986/*[clinic input]
8987os._fcopyfile
8988
8989 infd: int
8990 outfd: int
8991 flags: int
8992 /
8993
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008994Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02008995[clinic start generated code]*/
8996
8997static PyObject *
8998os__fcopyfile_impl(PyObject *module, int infd, int outfd, int flags)
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07008999/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009000{
9001 int ret;
9002
9003 Py_BEGIN_ALLOW_THREADS
9004 ret = fcopyfile(infd, outfd, NULL, flags);
9005 Py_END_ALLOW_THREADS
9006 if (ret < 0)
9007 return posix_error();
9008 Py_RETURN_NONE;
9009}
9010#endif
9011
9012
Larry Hastings2f936352014-08-05 14:04:04 +10009013/*[clinic input]
9014os.fstat
9015
9016 fd : int
9017
9018Perform a stat system call on the given file descriptor.
9019
9020Like stat(), but for an open file descriptor.
9021Equivalent to os.stat(fd).
9022[clinic start generated code]*/
9023
Larry Hastings2f936352014-08-05 14:04:04 +10009024static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009025os_fstat_impl(PyObject *module, int fd)
9026/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009027{
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 STRUCT_STAT st;
9029 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009030 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009031
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009032 do {
9033 Py_BEGIN_ALLOW_THREADS
9034 res = FSTAT(fd, &st);
9035 Py_END_ALLOW_THREADS
9036 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009037 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009038#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009039 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009040#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009041 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009042#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009043 }
Tim Peters5aa91602002-01-30 05:46:57 +00009044
Victor Stinner4195b5c2012-02-08 23:03:19 +01009045 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009046}
9047
Larry Hastings2f936352014-08-05 14:04:04 +10009048
9049/*[clinic input]
9050os.isatty -> bool
9051 fd: int
9052 /
9053
9054Return True if the fd is connected to a terminal.
9055
9056Return True if the file descriptor is an open file descriptor
9057connected to the slave end of a terminal.
9058[clinic start generated code]*/
9059
Larry Hastings2f936352014-08-05 14:04:04 +10009060static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009061os_isatty_impl(PyObject *module, int fd)
9062/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009063{
Steve Dower8fc89802015-04-12 00:26:27 -04009064 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009065 _Py_BEGIN_SUPPRESS_IPH
9066 return_value = isatty(fd);
9067 _Py_END_SUPPRESS_IPH
9068 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009069}
9070
9071
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009072#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009073/*[clinic input]
9074os.pipe
9075
9076Create a pipe.
9077
9078Returns a tuple of two file descriptors:
9079 (read_fd, write_fd)
9080[clinic start generated code]*/
9081
Larry Hastings2f936352014-08-05 14:04:04 +10009082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009083os_pipe_impl(PyObject *module)
9084/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009085{
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009087#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009088 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009089 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009090 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009091#else
9092 int res;
9093#endif
9094
9095#ifdef MS_WINDOWS
9096 attr.nLength = sizeof(attr);
9097 attr.lpSecurityDescriptor = NULL;
9098 attr.bInheritHandle = FALSE;
9099
9100 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009101 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009102 ok = CreatePipe(&read, &write, &attr, 0);
9103 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009104 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9105 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009106 if (fds[0] == -1 || fds[1] == -1) {
9107 CloseHandle(read);
9108 CloseHandle(write);
9109 ok = 0;
9110 }
9111 }
Steve Dowerc3630612016-11-19 18:41:16 -08009112 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009113 Py_END_ALLOW_THREADS
9114
Victor Stinner8c62be82010-05-06 00:08:46 +00009115 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009116 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009117#else
9118
9119#ifdef HAVE_PIPE2
9120 Py_BEGIN_ALLOW_THREADS
9121 res = pipe2(fds, O_CLOEXEC);
9122 Py_END_ALLOW_THREADS
9123
9124 if (res != 0 && errno == ENOSYS)
9125 {
9126#endif
9127 Py_BEGIN_ALLOW_THREADS
9128 res = pipe(fds);
9129 Py_END_ALLOW_THREADS
9130
9131 if (res == 0) {
9132 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9133 close(fds[0]);
9134 close(fds[1]);
9135 return NULL;
9136 }
9137 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9138 close(fds[0]);
9139 close(fds[1]);
9140 return NULL;
9141 }
9142 }
9143#ifdef HAVE_PIPE2
9144 }
9145#endif
9146
9147 if (res != 0)
9148 return PyErr_SetFromErrno(PyExc_OSError);
9149#endif /* !MS_WINDOWS */
9150 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009151}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009152#endif /* HAVE_PIPE */
9153
Larry Hastings2f936352014-08-05 14:04:04 +10009154
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009155#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009156/*[clinic input]
9157os.pipe2
9158
9159 flags: int
9160 /
9161
9162Create a pipe with flags set atomically.
9163
9164Returns a tuple of two file descriptors:
9165 (read_fd, write_fd)
9166
9167flags can be constructed by ORing together one or more of these values:
9168O_NONBLOCK, O_CLOEXEC.
9169[clinic start generated code]*/
9170
Larry Hastings2f936352014-08-05 14:04:04 +10009171static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009172os_pipe2_impl(PyObject *module, int flags)
9173/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009174{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009175 int fds[2];
9176 int res;
9177
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009178 res = pipe2(fds, flags);
9179 if (res != 0)
9180 return posix_error();
9181 return Py_BuildValue("(ii)", fds[0], fds[1]);
9182}
9183#endif /* HAVE_PIPE2 */
9184
Larry Hastings2f936352014-08-05 14:04:04 +10009185
Ross Lagerwall7807c352011-03-17 20:20:30 +02009186#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009187/*[clinic input]
9188os.writev -> Py_ssize_t
9189 fd: int
9190 buffers: object
9191 /
9192
9193Iterate over buffers, and write the contents of each to a file descriptor.
9194
9195Returns the total number of bytes written.
9196buffers must be a sequence of bytes-like objects.
9197[clinic start generated code]*/
9198
Larry Hastings2f936352014-08-05 14:04:04 +10009199static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009200os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9201/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009202{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009203 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009204 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009205 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009206 struct iovec *iov;
9207 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009208
9209 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009210 PyErr_SetString(PyExc_TypeError,
9211 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009212 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009213 }
Larry Hastings2f936352014-08-05 14:04:04 +10009214 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009215 if (cnt < 0)
9216 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009217
Larry Hastings2f936352014-08-05 14:04:04 +10009218 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9219 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009220 }
9221
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009222 do {
9223 Py_BEGIN_ALLOW_THREADS
9224 result = writev(fd, iov, cnt);
9225 Py_END_ALLOW_THREADS
9226 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009227
9228 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009229 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009230 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009231
Georg Brandl306336b2012-06-24 12:55:33 +02009232 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009233}
Larry Hastings2f936352014-08-05 14:04:04 +10009234#endif /* HAVE_WRITEV */
9235
9236
9237#ifdef HAVE_PWRITE
9238/*[clinic input]
9239os.pwrite -> Py_ssize_t
9240
9241 fd: int
9242 buffer: Py_buffer
9243 offset: Py_off_t
9244 /
9245
9246Write bytes to a file descriptor starting at a particular offset.
9247
9248Write buffer to fd, starting at offset bytes from the beginning of
9249the file. Returns the number of bytes writte. Does not change the
9250current file offset.
9251[clinic start generated code]*/
9252
Larry Hastings2f936352014-08-05 14:04:04 +10009253static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009254os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9255/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009256{
9257 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009258 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009259
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009260 do {
9261 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009262 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009263 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009264 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009265 Py_END_ALLOW_THREADS
9266 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009267
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009268 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009269 posix_error();
9270 return size;
9271}
9272#endif /* HAVE_PWRITE */
9273
Pablo Galindo4defba32018-01-27 16:16:37 +00009274#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9275/*[clinic input]
9276os.pwritev -> Py_ssize_t
9277
9278 fd: int
9279 buffers: object
9280 offset: Py_off_t
9281 flags: int = 0
9282 /
9283
9284Writes the contents of bytes-like objects to a file descriptor at a given offset.
9285
9286Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9287of bytes-like objects. Buffers are processed in array order. Entire contents of first
9288buffer is written before proceeding to second, and so on. The operating system may
9289set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9290This function writes the contents of each object to the file descriptor and returns
9291the total number of bytes written.
9292
9293The flags argument contains a bitwise OR of zero or more of the following flags:
9294
9295- RWF_DSYNC
9296- RWF_SYNC
9297
9298Using non-zero flags requires Linux 4.7 or newer.
9299[clinic start generated code]*/
9300
9301static Py_ssize_t
9302os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9303 int flags)
9304/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9305{
9306 Py_ssize_t cnt;
9307 Py_ssize_t result;
9308 int async_err = 0;
9309 struct iovec *iov;
9310 Py_buffer *buf;
9311
9312 if (!PySequence_Check(buffers)) {
9313 PyErr_SetString(PyExc_TypeError,
9314 "pwritev() arg 2 must be a sequence");
9315 return -1;
9316 }
9317
9318 cnt = PySequence_Size(buffers);
9319 if (cnt < 0) {
9320 return -1;
9321 }
9322
9323#ifndef HAVE_PWRITEV2
9324 if(flags != 0) {
9325 argument_unavailable_error("pwritev2", "flags");
9326 return -1;
9327 }
9328#endif
9329
9330 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9331 return -1;
9332 }
9333#ifdef HAVE_PWRITEV2
9334 do {
9335 Py_BEGIN_ALLOW_THREADS
9336 _Py_BEGIN_SUPPRESS_IPH
9337 result = pwritev2(fd, iov, cnt, offset, flags);
9338 _Py_END_SUPPRESS_IPH
9339 Py_END_ALLOW_THREADS
9340 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9341#else
9342 do {
9343 Py_BEGIN_ALLOW_THREADS
9344 _Py_BEGIN_SUPPRESS_IPH
9345 result = pwritev(fd, iov, cnt, offset);
9346 _Py_END_SUPPRESS_IPH
9347 Py_END_ALLOW_THREADS
9348 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9349#endif
9350
9351 iov_cleanup(iov, buf, cnt);
9352 if (result < 0) {
9353 if (!async_err) {
9354 posix_error();
9355 }
9356 return -1;
9357 }
9358
9359 return result;
9360}
9361#endif /* HAVE_PWRITEV */
9362
9363
9364
Larry Hastings2f936352014-08-05 14:04:04 +10009365
9366#ifdef HAVE_MKFIFO
9367/*[clinic input]
9368os.mkfifo
9369
9370 path: path_t
9371 mode: int=0o666
9372 *
9373 dir_fd: dir_fd(requires='mkfifoat')=None
9374
9375Create a "fifo" (a POSIX named pipe).
9376
9377If dir_fd is not None, it should be a file descriptor open to a directory,
9378 and path should be relative; path will then be relative to that directory.
9379dir_fd may not be implemented on your platform.
9380 If it is unavailable, using it will raise a NotImplementedError.
9381[clinic start generated code]*/
9382
Larry Hastings2f936352014-08-05 14:04:04 +10009383static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009384os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9385/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009386{
9387 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009388 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009389
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009390 do {
9391 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009392#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009393 if (dir_fd != DEFAULT_DIR_FD)
9394 result = mkfifoat(dir_fd, path->narrow, mode);
9395 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009396#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009397 result = mkfifo(path->narrow, mode);
9398 Py_END_ALLOW_THREADS
9399 } while (result != 0 && errno == EINTR &&
9400 !(async_err = PyErr_CheckSignals()));
9401 if (result != 0)
9402 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009403
9404 Py_RETURN_NONE;
9405}
9406#endif /* HAVE_MKFIFO */
9407
9408
9409#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9410/*[clinic input]
9411os.mknod
9412
9413 path: path_t
9414 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009415 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009416 *
9417 dir_fd: dir_fd(requires='mknodat')=None
9418
9419Create a node in the file system.
9420
9421Create a node in the file system (file, device special file or named pipe)
9422at path. mode specifies both the permissions to use and the
9423type of node to be created, being combined (bitwise OR) with one of
9424S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9425device defines the newly created device special file (probably using
9426os.makedev()). Otherwise device is ignored.
9427
9428If dir_fd is not None, it should be a file descriptor open to a directory,
9429 and path should be relative; path will then be relative to that directory.
9430dir_fd may not be implemented on your platform.
9431 If it is unavailable, using it will raise a NotImplementedError.
9432[clinic start generated code]*/
9433
Larry Hastings2f936352014-08-05 14:04:04 +10009434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009435os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009436 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009437/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009438{
9439 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009440 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009441
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009442 do {
9443 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009444#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009445 if (dir_fd != DEFAULT_DIR_FD)
9446 result = mknodat(dir_fd, path->narrow, mode, device);
9447 else
Larry Hastings2f936352014-08-05 14:04:04 +10009448#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009449 result = mknod(path->narrow, mode, device);
9450 Py_END_ALLOW_THREADS
9451 } while (result != 0 && errno == EINTR &&
9452 !(async_err = PyErr_CheckSignals()));
9453 if (result != 0)
9454 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009455
9456 Py_RETURN_NONE;
9457}
9458#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
9459
9460
9461#ifdef HAVE_DEVICE_MACROS
9462/*[clinic input]
9463os.major -> unsigned_int
9464
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009465 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009466 /
9467
9468Extracts a device major number from a raw device number.
9469[clinic start generated code]*/
9470
Larry Hastings2f936352014-08-05 14:04:04 +10009471static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009472os_major_impl(PyObject *module, dev_t device)
9473/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009474{
9475 return major(device);
9476}
9477
9478
9479/*[clinic input]
9480os.minor -> unsigned_int
9481
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009482 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009483 /
9484
9485Extracts a device minor number from a raw device number.
9486[clinic start generated code]*/
9487
Larry Hastings2f936352014-08-05 14:04:04 +10009488static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009489os_minor_impl(PyObject *module, dev_t device)
9490/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009491{
9492 return minor(device);
9493}
9494
9495
9496/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009497os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10009498
9499 major: int
9500 minor: int
9501 /
9502
9503Composes a raw device number from the major and minor device numbers.
9504[clinic start generated code]*/
9505
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009506static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009507os_makedev_impl(PyObject *module, int major, int minor)
9508/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009509{
9510 return makedev(major, minor);
9511}
9512#endif /* HAVE_DEVICE_MACROS */
9513
9514
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009515#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009516/*[clinic input]
9517os.ftruncate
9518
9519 fd: int
9520 length: Py_off_t
9521 /
9522
9523Truncate a file, specified by file descriptor, to a specific length.
9524[clinic start generated code]*/
9525
Larry Hastings2f936352014-08-05 14:04:04 +10009526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009527os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9528/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009529{
9530 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009531 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009532
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009533 do {
9534 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009535 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009536#ifdef MS_WINDOWS
9537 result = _chsize_s(fd, length);
9538#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009539 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009540#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009541 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009542 Py_END_ALLOW_THREADS
9543 } while (result != 0 && errno == EINTR &&
9544 !(async_err = PyErr_CheckSignals()));
9545 if (result != 0)
9546 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009547 Py_RETURN_NONE;
9548}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009549#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009550
9551
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009552#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009553/*[clinic input]
9554os.truncate
9555 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9556 length: Py_off_t
9557
9558Truncate a file, specified by path, to a specific length.
9559
9560On some platforms, path may also be specified as an open file descriptor.
9561 If this functionality is unavailable, using it raises an exception.
9562[clinic start generated code]*/
9563
Larry Hastings2f936352014-08-05 14:04:04 +10009564static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009565os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9566/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009567{
9568 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009569#ifdef MS_WINDOWS
9570 int fd;
9571#endif
9572
9573 if (path->fd != -1)
9574 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009575
9576 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009577 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009578#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009579 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009580 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009581 result = -1;
9582 else {
9583 result = _chsize_s(fd, length);
9584 close(fd);
9585 if (result < 0)
9586 errno = result;
9587 }
9588#else
9589 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009590#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009591 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009592 Py_END_ALLOW_THREADS
9593 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +03009594 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009595
9596 Py_RETURN_NONE;
9597}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009598#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009599
Ross Lagerwall7807c352011-03-17 20:20:30 +02009600
Victor Stinnerd6b17692014-09-30 12:20:05 +02009601/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9602 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9603 defined, which is the case in Python on AIX. AIX bug report:
9604 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9605#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9606# define POSIX_FADVISE_AIX_BUG
9607#endif
9608
Victor Stinnerec39e262014-09-30 12:35:58 +02009609
Victor Stinnerd6b17692014-09-30 12:20:05 +02009610#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009611/*[clinic input]
9612os.posix_fallocate
9613
9614 fd: int
9615 offset: Py_off_t
9616 length: Py_off_t
9617 /
9618
9619Ensure a file has allocated at least a particular number of bytes on disk.
9620
9621Ensure that the file specified by fd encompasses a range of bytes
9622starting at offset bytes from the beginning and continuing for length bytes.
9623[clinic start generated code]*/
9624
Larry Hastings2f936352014-08-05 14:04:04 +10009625static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009626os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009627 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009628/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009629{
9630 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009631 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009632
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009633 do {
9634 Py_BEGIN_ALLOW_THREADS
9635 result = posix_fallocate(fd, offset, length);
9636 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009637 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9638
9639 if (result == 0)
9640 Py_RETURN_NONE;
9641
9642 if (async_err)
9643 return NULL;
9644
9645 errno = result;
9646 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009647}
Victor Stinnerec39e262014-09-30 12:35:58 +02009648#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009649
Ross Lagerwall7807c352011-03-17 20:20:30 +02009650
Victor Stinnerd6b17692014-09-30 12:20:05 +02009651#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009652/*[clinic input]
9653os.posix_fadvise
9654
9655 fd: int
9656 offset: Py_off_t
9657 length: Py_off_t
9658 advice: int
9659 /
9660
9661Announce an intention to access data in a specific pattern.
9662
9663Announce an intention to access data in a specific pattern, thus allowing
9664the kernel to make optimizations.
9665The advice applies to the region of the file specified by fd starting at
9666offset and continuing for length bytes.
9667advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9668POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9669POSIX_FADV_DONTNEED.
9670[clinic start generated code]*/
9671
Larry Hastings2f936352014-08-05 14:04:04 +10009672static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009673os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009674 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009675/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009676{
9677 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009678 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009679
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009680 do {
9681 Py_BEGIN_ALLOW_THREADS
9682 result = posix_fadvise(fd, offset, length, advice);
9683 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009684 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9685
9686 if (result == 0)
9687 Py_RETURN_NONE;
9688
9689 if (async_err)
9690 return NULL;
9691
9692 errno = result;
9693 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009694}
Victor Stinnerec39e262014-09-30 12:35:58 +02009695#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009696
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009697#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009698
Fred Drake762e2061999-08-26 17:23:54 +00009699/* Save putenv() parameters as values here, so we can collect them when they
9700 * get re-set with another call for the same key. */
9701static PyObject *posix_putenv_garbage;
9702
Larry Hastings2f936352014-08-05 14:04:04 +10009703static void
9704posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009705{
Larry Hastings2f936352014-08-05 14:04:04 +10009706 /* Install the first arg and newstr in posix_putenv_garbage;
9707 * this will cause previous value to be collected. This has to
9708 * happen after the real putenv() call because the old value
9709 * was still accessible until then. */
9710 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9711 /* really not much we can do; just leak */
9712 PyErr_Clear();
9713 else
9714 Py_DECREF(value);
9715}
9716
9717
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009718#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009719/*[clinic input]
9720os.putenv
9721
9722 name: unicode
9723 value: unicode
9724 /
9725
9726Change or add an environment variable.
9727[clinic start generated code]*/
9728
Larry Hastings2f936352014-08-05 14:04:04 +10009729static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009730os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9731/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009732{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009733 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009734 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009735
Serhiy Storchaka77703942017-06-25 07:33:01 +03009736 /* Search from index 1 because on Windows starting '=' is allowed for
9737 defining hidden environment variables. */
9738 if (PyUnicode_GET_LENGTH(name) == 0 ||
9739 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9740 {
9741 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9742 return NULL;
9743 }
Larry Hastings2f936352014-08-05 14:04:04 +10009744 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9745 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009746 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009747 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009748
9749 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9750 if (env == NULL)
9751 goto error;
9752 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009753 PyErr_Format(PyExc_ValueError,
9754 "the environment variable is longer than %u characters",
9755 _MAX_ENV);
9756 goto error;
9757 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009758 if (wcslen(env) != (size_t)size) {
9759 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009760 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009761 }
9762
Larry Hastings2f936352014-08-05 14:04:04 +10009763 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009765 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009767
Larry Hastings2f936352014-08-05 14:04:04 +10009768 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009769 Py_RETURN_NONE;
9770
9771error:
Larry Hastings2f936352014-08-05 14:04:04 +10009772 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009773 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009774}
Larry Hastings2f936352014-08-05 14:04:04 +10009775#else /* MS_WINDOWS */
9776/*[clinic input]
9777os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009778
Larry Hastings2f936352014-08-05 14:04:04 +10009779 name: FSConverter
9780 value: FSConverter
9781 /
9782
9783Change or add an environment variable.
9784[clinic start generated code]*/
9785
Larry Hastings2f936352014-08-05 14:04:04 +10009786static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009787os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9788/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009789{
9790 PyObject *bytes = NULL;
9791 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009792 const char *name_string = PyBytes_AS_STRING(name);
9793 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009794
Serhiy Storchaka77703942017-06-25 07:33:01 +03009795 if (strchr(name_string, '=') != NULL) {
9796 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9797 return NULL;
9798 }
Larry Hastings2f936352014-08-05 14:04:04 +10009799 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9800 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009801 return NULL;
9802 }
9803
9804 env = PyBytes_AS_STRING(bytes);
9805 if (putenv(env)) {
9806 Py_DECREF(bytes);
9807 return posix_error();
9808 }
9809
9810 posix_putenv_garbage_setitem(name, bytes);
9811 Py_RETURN_NONE;
9812}
9813#endif /* MS_WINDOWS */
9814#endif /* HAVE_PUTENV */
9815
9816
9817#ifdef HAVE_UNSETENV
9818/*[clinic input]
9819os.unsetenv
9820 name: FSConverter
9821 /
9822
9823Delete an environment variable.
9824[clinic start generated code]*/
9825
Larry Hastings2f936352014-08-05 14:04:04 +10009826static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009827os_unsetenv_impl(PyObject *module, PyObject *name)
9828/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009829{
Victor Stinner984890f2011-11-24 13:53:38 +01009830#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009831 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009832#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009833
Victor Stinner984890f2011-11-24 13:53:38 +01009834#ifdef HAVE_BROKEN_UNSETENV
9835 unsetenv(PyBytes_AS_STRING(name));
9836#else
Victor Stinner65170952011-11-22 22:16:17 +01009837 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009838 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009839 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009840#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009841
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 /* Remove the key from posix_putenv_garbage;
9843 * this will cause it to be collected. This has to
9844 * happen after the real unsetenv() call because the
9845 * old value was still accessible until then.
9846 */
Victor Stinner65170952011-11-22 22:16:17 +01009847 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 /* really not much we can do; just leak */
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02009849 if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
9850 return NULL;
9851 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 PyErr_Clear();
9853 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009854 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009855}
Larry Hastings2f936352014-08-05 14:04:04 +10009856#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009857
Larry Hastings2f936352014-08-05 14:04:04 +10009858
9859/*[clinic input]
9860os.strerror
9861
9862 code: int
9863 /
9864
9865Translate an error code to a message string.
9866[clinic start generated code]*/
9867
Larry Hastings2f936352014-08-05 14:04:04 +10009868static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009869os_strerror_impl(PyObject *module, int code)
9870/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009871{
9872 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 if (message == NULL) {
9874 PyErr_SetString(PyExc_ValueError,
9875 "strerror() argument out of range");
9876 return NULL;
9877 }
Victor Stinner1b579672011-12-17 05:47:23 +01009878 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009879}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009880
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009881
Guido van Rossumc9641791998-08-04 15:26:23 +00009882#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009883#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009884/*[clinic input]
9885os.WCOREDUMP -> bool
9886
9887 status: int
9888 /
9889
9890Return True if the process returning status was dumped to a core file.
9891[clinic start generated code]*/
9892
Larry Hastings2f936352014-08-05 14:04:04 +10009893static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009894os_WCOREDUMP_impl(PyObject *module, int status)
9895/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009896{
9897 WAIT_TYPE wait_status;
9898 WAIT_STATUS_INT(wait_status) = status;
9899 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009900}
9901#endif /* WCOREDUMP */
9902
Larry Hastings2f936352014-08-05 14:04:04 +10009903
Fred Drake106c1a02002-04-23 15:58:02 +00009904#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009905/*[clinic input]
9906os.WIFCONTINUED -> bool
9907
9908 status: int
9909
9910Return True if a particular process was continued from a job control stop.
9911
9912Return True if the process returning status was continued from a
9913job control stop.
9914[clinic start generated code]*/
9915
Larry Hastings2f936352014-08-05 14:04:04 +10009916static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009917os_WIFCONTINUED_impl(PyObject *module, int status)
9918/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009919{
9920 WAIT_TYPE wait_status;
9921 WAIT_STATUS_INT(wait_status) = status;
9922 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009923}
9924#endif /* WIFCONTINUED */
9925
Larry Hastings2f936352014-08-05 14:04:04 +10009926
Guido van Rossumc9641791998-08-04 15:26:23 +00009927#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009928/*[clinic input]
9929os.WIFSTOPPED -> bool
9930
9931 status: int
9932
9933Return True if the process returning status was stopped.
9934[clinic start generated code]*/
9935
Larry Hastings2f936352014-08-05 14:04:04 +10009936static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009937os_WIFSTOPPED_impl(PyObject *module, int status)
9938/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009939{
9940 WAIT_TYPE wait_status;
9941 WAIT_STATUS_INT(wait_status) = status;
9942 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009943}
9944#endif /* WIFSTOPPED */
9945
Larry Hastings2f936352014-08-05 14:04:04 +10009946
Guido van Rossumc9641791998-08-04 15:26:23 +00009947#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009948/*[clinic input]
9949os.WIFSIGNALED -> bool
9950
9951 status: int
9952
9953Return True if the process returning status was terminated by a signal.
9954[clinic start generated code]*/
9955
Larry Hastings2f936352014-08-05 14:04:04 +10009956static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009957os_WIFSIGNALED_impl(PyObject *module, int status)
9958/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009959{
9960 WAIT_TYPE wait_status;
9961 WAIT_STATUS_INT(wait_status) = status;
9962 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009963}
9964#endif /* WIFSIGNALED */
9965
Larry Hastings2f936352014-08-05 14:04:04 +10009966
Guido van Rossumc9641791998-08-04 15:26:23 +00009967#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009968/*[clinic input]
9969os.WIFEXITED -> bool
9970
9971 status: int
9972
9973Return True if the process returning status exited via the exit() system call.
9974[clinic start generated code]*/
9975
Larry Hastings2f936352014-08-05 14:04:04 +10009976static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009977os_WIFEXITED_impl(PyObject *module, int status)
9978/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009979{
9980 WAIT_TYPE wait_status;
9981 WAIT_STATUS_INT(wait_status) = status;
9982 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009983}
9984#endif /* WIFEXITED */
9985
Larry Hastings2f936352014-08-05 14:04:04 +10009986
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009987#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009988/*[clinic input]
9989os.WEXITSTATUS -> int
9990
9991 status: int
9992
9993Return the process return code from status.
9994[clinic start generated code]*/
9995
Larry Hastings2f936352014-08-05 14:04:04 +10009996static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009997os_WEXITSTATUS_impl(PyObject *module, int status)
9998/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009999{
10000 WAIT_TYPE wait_status;
10001 WAIT_STATUS_INT(wait_status) = status;
10002 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010003}
10004#endif /* WEXITSTATUS */
10005
Larry Hastings2f936352014-08-05 14:04:04 +100010006
Guido van Rossumc9641791998-08-04 15:26:23 +000010007#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010008/*[clinic input]
10009os.WTERMSIG -> int
10010
10011 status: int
10012
10013Return the signal that terminated the process that provided the status value.
10014[clinic start generated code]*/
10015
Larry Hastings2f936352014-08-05 14:04:04 +100010016static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010017os_WTERMSIG_impl(PyObject *module, int status)
10018/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010019{
10020 WAIT_TYPE wait_status;
10021 WAIT_STATUS_INT(wait_status) = status;
10022 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010023}
10024#endif /* WTERMSIG */
10025
Larry Hastings2f936352014-08-05 14:04:04 +100010026
Guido van Rossumc9641791998-08-04 15:26:23 +000010027#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010028/*[clinic input]
10029os.WSTOPSIG -> int
10030
10031 status: int
10032
10033Return the signal that stopped the process that provided the status value.
10034[clinic start generated code]*/
10035
Larry Hastings2f936352014-08-05 14:04:04 +100010036static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010037os_WSTOPSIG_impl(PyObject *module, int status)
10038/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010039{
10040 WAIT_TYPE wait_status;
10041 WAIT_STATUS_INT(wait_status) = status;
10042 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010043}
10044#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010045#endif /* HAVE_SYS_WAIT_H */
10046
10047
Thomas Wouters477c8d52006-05-27 19:21:47 +000010048#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010049#ifdef _SCO_DS
10050/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10051 needed definitions in sys/statvfs.h */
10052#define _SVID3
10053#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010054#include <sys/statvfs.h>
10055
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010056static PyObject*
10057_pystatvfs_fromstructstatvfs(struct statvfs st) {
Eddie Elizondo474eedf2018-11-13 04:09:31 -080010058 PyObject *v = PyStructSequence_New(StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 if (v == NULL)
10060 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010061
10062#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10064 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10065 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10066 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10067 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10068 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10069 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10070 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10071 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10072 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010073#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10075 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10076 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010077 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010079 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010081 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010083 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010085 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010087 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10089 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010090#endif
Michael Felt502d5512018-01-05 13:01:58 +010010091/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10092 * (issue #32390). */
10093#if defined(_AIX) && defined(_ALL_SOURCE)
10094 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10095#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010096 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010097#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010098 if (PyErr_Occurred()) {
10099 Py_DECREF(v);
10100 return NULL;
10101 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010102
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010104}
10105
Larry Hastings2f936352014-08-05 14:04:04 +100010106
10107/*[clinic input]
10108os.fstatvfs
10109 fd: int
10110 /
10111
10112Perform an fstatvfs system call on the given fd.
10113
10114Equivalent to statvfs(fd).
10115[clinic start generated code]*/
10116
Larry Hastings2f936352014-08-05 14:04:04 +100010117static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010118os_fstatvfs_impl(PyObject *module, int fd)
10119/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010120{
10121 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010122 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010124
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010125 do {
10126 Py_BEGIN_ALLOW_THREADS
10127 result = fstatvfs(fd, &st);
10128 Py_END_ALLOW_THREADS
10129 } while (result != 0 && errno == EINTR &&
10130 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010131 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010132 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010133
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010135}
Larry Hastings2f936352014-08-05 14:04:04 +100010136#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010137
10138
Thomas Wouters477c8d52006-05-27 19:21:47 +000010139#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010140#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010141/*[clinic input]
10142os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010143
Larry Hastings2f936352014-08-05 14:04:04 +100010144 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10145
10146Perform a statvfs system call on the given path.
10147
10148path may always be specified as a string.
10149On some platforms, path may also be specified as an open file descriptor.
10150 If this functionality is unavailable, using it raises an exception.
10151[clinic start generated code]*/
10152
Larry Hastings2f936352014-08-05 14:04:04 +100010153static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010154os_statvfs_impl(PyObject *module, path_t *path)
10155/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010156{
10157 int result;
10158 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010159
10160 Py_BEGIN_ALLOW_THREADS
10161#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010162 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010163#ifdef __APPLE__
10164 /* handle weak-linking on Mac OS X 10.3 */
10165 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010166 fd_specified("statvfs", path->fd);
10167 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010168 }
10169#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010170 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010171 }
10172 else
10173#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010174 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010175 Py_END_ALLOW_THREADS
10176
10177 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010178 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010179 }
10180
Larry Hastings2f936352014-08-05 14:04:04 +100010181 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010182}
Larry Hastings2f936352014-08-05 14:04:04 +100010183#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10184
Guido van Rossum94f6f721999-01-06 18:42:14 +000010185
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010186#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010187/*[clinic input]
10188os._getdiskusage
10189
Steve Dower23ad6d02018-02-22 10:39:10 -080010190 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010191
10192Return disk usage statistics about the given path as a (total, free) tuple.
10193[clinic start generated code]*/
10194
Larry Hastings2f936352014-08-05 14:04:04 +100010195static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010196os__getdiskusage_impl(PyObject *module, path_t *path)
10197/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010198{
10199 BOOL retval;
10200 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010201 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010202
10203 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010204 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010205 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010206 if (retval == 0) {
10207 if (GetLastError() == ERROR_DIRECTORY) {
10208 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010209
Joe Pamerc8c02492018-09-25 10:57:36 -040010210 dir_path = PyMem_New(wchar_t, path->length + 1);
10211 if (dir_path == NULL) {
10212 return PyErr_NoMemory();
10213 }
10214
10215 wcscpy_s(dir_path, path->length + 1, path->wide);
10216
10217 if (_dirnameW(dir_path) != -1) {
10218 Py_BEGIN_ALLOW_THREADS
10219 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10220 Py_END_ALLOW_THREADS
10221 }
10222 /* Record the last error in case it's modified by PyMem_Free. */
10223 err = GetLastError();
10224 PyMem_Free(dir_path);
10225 if (retval) {
10226 goto success;
10227 }
10228 }
10229 return PyErr_SetFromWindowsErr(err);
10230 }
10231
10232success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010233 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10234}
Larry Hastings2f936352014-08-05 14:04:04 +100010235#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010236
10237
Fred Drakec9680921999-12-13 16:37:25 +000010238/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10239 * It maps strings representing configuration variable names to
10240 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010241 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010242 * rarely-used constants. There are three separate tables that use
10243 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010244 *
10245 * This code is always included, even if none of the interfaces that
10246 * need it are included. The #if hackery needed to avoid it would be
10247 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010248 */
10249struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010250 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010251 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010252};
10253
Fred Drake12c6e2d1999-12-14 21:25:03 +000010254static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010255conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010256 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010257{
Christian Heimes217cfd12007-12-02 14:31:20 +000010258 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010259 int value = _PyLong_AsInt(arg);
10260 if (value == -1 && PyErr_Occurred())
10261 return 0;
10262 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010263 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010264 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010265 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010266 /* look up the value in the table using a binary search */
10267 size_t lo = 0;
10268 size_t mid;
10269 size_t hi = tablesize;
10270 int cmp;
10271 const char *confname;
10272 if (!PyUnicode_Check(arg)) {
10273 PyErr_SetString(PyExc_TypeError,
10274 "configuration names must be strings or integers");
10275 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010277 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010278 if (confname == NULL)
10279 return 0;
10280 while (lo < hi) {
10281 mid = (lo + hi) / 2;
10282 cmp = strcmp(confname, table[mid].name);
10283 if (cmp < 0)
10284 hi = mid;
10285 else if (cmp > 0)
10286 lo = mid + 1;
10287 else {
10288 *valuep = table[mid].value;
10289 return 1;
10290 }
10291 }
10292 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10293 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010295}
10296
10297
10298#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10299static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010300#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010302#endif
10303#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010305#endif
Fred Drakec9680921999-12-13 16:37:25 +000010306#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010351#ifdef _PC_ACL_ENABLED
10352 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10353#endif
10354#ifdef _PC_MIN_HOLE_SIZE
10355 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10356#endif
10357#ifdef _PC_ALLOC_SIZE_MIN
10358 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10359#endif
10360#ifdef _PC_REC_INCR_XFER_SIZE
10361 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10362#endif
10363#ifdef _PC_REC_MAX_XFER_SIZE
10364 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10365#endif
10366#ifdef _PC_REC_MIN_XFER_SIZE
10367 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10368#endif
10369#ifdef _PC_REC_XFER_ALIGN
10370 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10371#endif
10372#ifdef _PC_SYMLINK_MAX
10373 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10374#endif
10375#ifdef _PC_XATTR_ENABLED
10376 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10377#endif
10378#ifdef _PC_XATTR_EXISTS
10379 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10380#endif
10381#ifdef _PC_TIMESTAMP_RESOLUTION
10382 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10383#endif
Fred Drakec9680921999-12-13 16:37:25 +000010384};
10385
Fred Drakec9680921999-12-13 16:37:25 +000010386static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010387conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010388{
10389 return conv_confname(arg, valuep, posix_constants_pathconf,
10390 sizeof(posix_constants_pathconf)
10391 / sizeof(struct constdef));
10392}
10393#endif
10394
Larry Hastings2f936352014-08-05 14:04:04 +100010395
Fred Drakec9680921999-12-13 16:37:25 +000010396#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010397/*[clinic input]
10398os.fpathconf -> long
10399
10400 fd: int
10401 name: path_confname
10402 /
10403
10404Return the configuration limit name for the file descriptor fd.
10405
10406If there is no limit, return -1.
10407[clinic start generated code]*/
10408
Larry Hastings2f936352014-08-05 14:04:04 +100010409static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010410os_fpathconf_impl(PyObject *module, int fd, int name)
10411/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010412{
10413 long limit;
10414
10415 errno = 0;
10416 limit = fpathconf(fd, name);
10417 if (limit == -1 && errno != 0)
10418 posix_error();
10419
10420 return limit;
10421}
10422#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010423
10424
10425#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010426/*[clinic input]
10427os.pathconf -> long
10428 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10429 name: path_confname
10430
10431Return the configuration limit name for the file or directory path.
10432
10433If there is no limit, return -1.
10434On some platforms, path may also be specified as an open file descriptor.
10435 If this functionality is unavailable, using it raises an exception.
10436[clinic start generated code]*/
10437
Larry Hastings2f936352014-08-05 14:04:04 +100010438static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010439os_pathconf_impl(PyObject *module, path_t *path, int name)
10440/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010441{
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010443
Victor Stinner8c62be82010-05-06 00:08:46 +000010444 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010445#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010446 if (path->fd != -1)
10447 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020010448 else
10449#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010450 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 if (limit == -1 && errno != 0) {
10452 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000010453 /* could be a path or name problem */
10454 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000010455 else
Larry Hastings2f936352014-08-05 14:04:04 +100010456 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 }
Larry Hastings2f936352014-08-05 14:04:04 +100010458
10459 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000010460}
Larry Hastings2f936352014-08-05 14:04:04 +100010461#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010462
10463#ifdef HAVE_CONFSTR
10464static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010465#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000010467#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000010468#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010470#endif
10471#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000010473#endif
Fred Draked86ed291999-12-15 15:34:33 +000010474#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010476#endif
10477#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010479#endif
10480#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010482#endif
10483#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010485#endif
Fred Drakec9680921999-12-13 16:37:25 +000010486#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010488#endif
10489#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010491#endif
10492#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010494#endif
10495#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010496 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010497#endif
10498#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010500#endif
10501#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010503#endif
10504#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010506#endif
10507#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010509#endif
Fred Draked86ed291999-12-15 15:34:33 +000010510#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000010512#endif
Fred Drakec9680921999-12-13 16:37:25 +000010513#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000010515#endif
Fred Draked86ed291999-12-15 15:34:33 +000010516#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010517 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000010518#endif
10519#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000010521#endif
10522#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000010524#endif
10525#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000010527#endif
Fred Drakec9680921999-12-13 16:37:25 +000010528#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010530#endif
10531#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010533#endif
10534#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010536#endif
10537#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010539#endif
10540#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010542#endif
10543#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010545#endif
10546#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010548#endif
10549#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010551#endif
10552#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010554#endif
10555#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010557#endif
10558#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010560#endif
10561#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010563#endif
10564#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010566#endif
10567#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010569#endif
10570#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010572#endif
10573#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010575#endif
Fred Draked86ed291999-12-15 15:34:33 +000010576#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010578#endif
10579#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010581#endif
10582#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010584#endif
10585#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010587#endif
10588#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010589 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010590#endif
10591#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010593#endif
10594#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010596#endif
10597#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010599#endif
10600#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010602#endif
10603#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010605#endif
10606#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010608#endif
10609#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010610 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010611#endif
10612#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010614#endif
Fred Drakec9680921999-12-13 16:37:25 +000010615};
10616
10617static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010618conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010619{
10620 return conv_confname(arg, valuep, posix_constants_confstr,
10621 sizeof(posix_constants_confstr)
10622 / sizeof(struct constdef));
10623}
10624
Larry Hastings2f936352014-08-05 14:04:04 +100010625
10626/*[clinic input]
10627os.confstr
10628
10629 name: confstr_confname
10630 /
10631
10632Return a string-valued system configuration variable.
10633[clinic start generated code]*/
10634
Larry Hastings2f936352014-08-05 14:04:04 +100010635static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010636os_confstr_impl(PyObject *module, int name)
10637/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010638{
10639 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010640 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010641 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010642
Victor Stinnercb043522010-09-10 23:49:04 +000010643 errno = 0;
10644 len = confstr(name, buffer, sizeof(buffer));
10645 if (len == 0) {
10646 if (errno) {
10647 posix_error();
10648 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010649 }
10650 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010651 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010652 }
10653 }
Victor Stinnercb043522010-09-10 23:49:04 +000010654
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010655 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010656 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010657 char *buf = PyMem_Malloc(len);
10658 if (buf == NULL)
10659 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010660 len2 = confstr(name, buf, len);
10661 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010662 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010663 PyMem_Free(buf);
10664 }
10665 else
10666 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010667 return result;
10668}
Larry Hastings2f936352014-08-05 14:04:04 +100010669#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010670
10671
10672#ifdef HAVE_SYSCONF
10673static struct constdef posix_constants_sysconf[] = {
10674#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010676#endif
10677#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010679#endif
10680#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010682#endif
10683#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010685#endif
10686#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010688#endif
10689#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010691#endif
10692#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010694#endif
10695#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010697#endif
10698#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010700#endif
10701#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010703#endif
Fred Draked86ed291999-12-15 15:34:33 +000010704#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010706#endif
10707#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010709#endif
Fred Drakec9680921999-12-13 16:37:25 +000010710#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010712#endif
Fred Drakec9680921999-12-13 16:37:25 +000010713#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010715#endif
10716#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010718#endif
10719#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010721#endif
10722#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010724#endif
10725#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010727#endif
Fred Draked86ed291999-12-15 15:34:33 +000010728#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010730#endif
Fred Drakec9680921999-12-13 16:37:25 +000010731#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010732 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010733#endif
10734#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010736#endif
10737#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010739#endif
10740#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010742#endif
10743#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010745#endif
Fred Draked86ed291999-12-15 15:34:33 +000010746#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010748#endif
Fred Drakec9680921999-12-13 16:37:25 +000010749#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010751#endif
10752#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010753 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010754#endif
10755#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010756 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010757#endif
10758#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010759 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010760#endif
10761#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010762 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010763#endif
10764#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010766#endif
10767#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010768 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010769#endif
10770#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010771 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010772#endif
10773#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010774 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010775#endif
10776#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010777 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010778#endif
10779#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010780 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010781#endif
10782#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010783 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010784#endif
10785#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010787#endif
10788#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010789 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010790#endif
10791#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010792 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010793#endif
10794#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010795 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010796#endif
10797#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010798 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010799#endif
10800#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010801 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010802#endif
10803#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010804 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010805#endif
10806#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010807 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010808#endif
10809#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010810 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010811#endif
10812#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010813 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010814#endif
10815#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010817#endif
Fred Draked86ed291999-12-15 15:34:33 +000010818#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010819 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010820#endif
Fred Drakec9680921999-12-13 16:37:25 +000010821#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010822 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010823#endif
10824#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010825 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010826#endif
10827#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010828 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010829#endif
Fred Draked86ed291999-12-15 15:34:33 +000010830#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010831 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010832#endif
Fred Drakec9680921999-12-13 16:37:25 +000010833#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010834 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010835#endif
Fred Draked86ed291999-12-15 15:34:33 +000010836#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010837 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010838#endif
10839#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010840 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010841#endif
Fred Drakec9680921999-12-13 16:37:25 +000010842#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010843 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010844#endif
10845#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010847#endif
10848#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010849 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010850#endif
10851#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010853#endif
Fred Draked86ed291999-12-15 15:34:33 +000010854#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010855 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010856#endif
Fred Drakec9680921999-12-13 16:37:25 +000010857#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010859#endif
10860#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010862#endif
10863#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010864 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010865#endif
10866#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010868#endif
10869#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010871#endif
10872#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010874#endif
10875#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010877#endif
Fred Draked86ed291999-12-15 15:34:33 +000010878#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010880#endif
Fred Drakec9680921999-12-13 16:37:25 +000010881#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010883#endif
10884#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010886#endif
Fred Draked86ed291999-12-15 15:34:33 +000010887#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010889#endif
Fred Drakec9680921999-12-13 16:37:25 +000010890#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010892#endif
10893#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010895#endif
10896#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010898#endif
10899#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010901#endif
10902#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010904#endif
10905#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010907#endif
10908#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010910#endif
10911#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010913#endif
10914#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010916#endif
Fred Draked86ed291999-12-15 15:34:33 +000010917#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010919#endif
10920#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010922#endif
Fred Drakec9680921999-12-13 16:37:25 +000010923#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010925#endif
10926#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010928#endif
10929#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010931#endif
10932#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010934#endif
10935#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010937#endif
10938#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010940#endif
10941#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010943#endif
10944#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010946#endif
10947#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010948 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010949#endif
10950#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010951 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010952#endif
10953#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010954 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010955#endif
10956#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010958#endif
10959#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010960 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010961#endif
10962#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010963 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010964#endif
10965#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010966 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010967#endif
10968#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010969 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010970#endif
10971#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010972 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010973#endif
10974#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010975 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010976#endif
10977#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010979#endif
10980#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010981 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010982#endif
10983#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010984 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010985#endif
10986#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010988#endif
10989#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010990 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010991#endif
10992#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010993 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010994#endif
10995#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010996 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010997#endif
10998#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010999 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011000#endif
11001#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011002 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011003#endif
11004#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011005 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011006#endif
11007#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011009#endif
11010#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011012#endif
11013#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011014 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011015#endif
11016#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011018#endif
11019#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011020 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011021#endif
11022#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011023 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011024#endif
11025#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011027#endif
Fred Draked86ed291999-12-15 15:34:33 +000011028#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011030#endif
Fred Drakec9680921999-12-13 16:37:25 +000011031#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011033#endif
11034#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011036#endif
11037#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011039#endif
11040#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011042#endif
11043#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011045#endif
11046#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011048#endif
11049#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011051#endif
11052#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011054#endif
11055#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011057#endif
11058#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011060#endif
11061#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011063#endif
11064#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011066#endif
11067#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011069#endif
11070#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011072#endif
11073#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011075#endif
11076#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011078#endif
11079#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011081#endif
11082#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011084#endif
11085#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011087#endif
11088#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011090#endif
11091#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011093#endif
11094#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011096#endif
11097#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011099#endif
11100#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011102#endif
11103#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011105#endif
11106#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011108#endif
11109#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011111#endif
11112#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011114#endif
11115#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011117#endif
11118#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011120#endif
11121#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011123#endif
11124#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011126#endif
11127#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011129#endif
11130#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011132#endif
11133#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011135#endif
11136#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011138#endif
11139#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011141#endif
11142#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011144#endif
11145#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011147#endif
11148#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011150#endif
11151#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011153#endif
11154#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011156#endif
11157#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011158 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011159#endif
11160#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011161 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011162#endif
11163#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011165#endif
11166};
11167
11168static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011169conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011170{
11171 return conv_confname(arg, valuep, posix_constants_sysconf,
11172 sizeof(posix_constants_sysconf)
11173 / sizeof(struct constdef));
11174}
11175
Larry Hastings2f936352014-08-05 14:04:04 +100011176
11177/*[clinic input]
11178os.sysconf -> long
11179 name: sysconf_confname
11180 /
11181
11182Return an integer-valued system configuration variable.
11183[clinic start generated code]*/
11184
Larry Hastings2f936352014-08-05 14:04:04 +100011185static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011186os_sysconf_impl(PyObject *module, int name)
11187/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011188{
11189 long value;
11190
11191 errno = 0;
11192 value = sysconf(name);
11193 if (value == -1 && errno != 0)
11194 posix_error();
11195 return value;
11196}
11197#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011198
11199
Fred Drakebec628d1999-12-15 18:31:10 +000011200/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011201 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011202 * the exported dictionaries that are used to publish information about the
11203 * names available on the host platform.
11204 *
11205 * Sorting the table at runtime ensures that the table is properly ordered
11206 * when used, even for platforms we're not able to test on. It also makes
11207 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011208 */
Fred Drakebec628d1999-12-15 18:31:10 +000011209
11210static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011211cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011212{
11213 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011215 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011216 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011217
11218 return strcmp(c1->name, c2->name);
11219}
11220
11221static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011222setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011223 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011224{
Fred Drakebec628d1999-12-15 18:31:10 +000011225 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011226 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011227
11228 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11229 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011230 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011231 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011232
Barry Warsaw3155db32000-04-13 15:20:40 +000011233 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011234 PyObject *o = PyLong_FromLong(table[i].value);
11235 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11236 Py_XDECREF(o);
11237 Py_DECREF(d);
11238 return -1;
11239 }
11240 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011241 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011242 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011243}
11244
Fred Drakebec628d1999-12-15 18:31:10 +000011245/* Return -1 on failure, 0 on success. */
11246static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011247setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011248{
11249#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011250 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011251 sizeof(posix_constants_pathconf)
11252 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011253 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011254 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011255#endif
11256#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011257 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011258 sizeof(posix_constants_confstr)
11259 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011260 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011261 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011262#endif
11263#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011264 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011265 sizeof(posix_constants_sysconf)
11266 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011267 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011268 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011269#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011270 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011271}
Fred Draked86ed291999-12-15 15:34:33 +000011272
11273
Larry Hastings2f936352014-08-05 14:04:04 +100011274/*[clinic input]
11275os.abort
11276
11277Abort the interpreter immediately.
11278
11279This function 'dumps core' or otherwise fails in the hardest way possible
11280on the hosting operating system. This function never returns.
11281[clinic start generated code]*/
11282
Larry Hastings2f936352014-08-05 14:04:04 +100011283static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011284os_abort_impl(PyObject *module)
11285/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011286{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011287 abort();
11288 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011289#ifndef __clang__
11290 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11291 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11292 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011293 Py_FatalError("abort() called from Python code didn't abort!");
11294 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011295#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011296}
Fred Drakebec628d1999-12-15 18:31:10 +000011297
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011298#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011299/* Grab ShellExecute dynamically from shell32 */
11300static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011301static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11302 LPCWSTR, INT);
11303static int
11304check_ShellExecute()
11305{
11306 HINSTANCE hShell32;
11307
11308 /* only recheck */
11309 if (-1 == has_ShellExecute) {
11310 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011311 /* Security note: this call is not vulnerable to "DLL hijacking".
11312 SHELL32 is part of "KnownDLLs" and so Windows always load
11313 the system SHELL32.DLL, even if there is another SHELL32.DLL
11314 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011315 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011316 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011317 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11318 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011319 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011320 } else {
11321 has_ShellExecute = 0;
11322 }
Tony Roberts4860f012019-02-02 18:16:42 +010011323 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011324 }
11325 return has_ShellExecute;
11326}
11327
11328
Steve Dowercc16be82016-09-08 10:35:16 -070011329/*[clinic input]
11330os.startfile
11331 filepath: path_t
11332 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011333
Steve Dowercc16be82016-09-08 10:35:16 -070011334startfile(filepath [, operation])
11335
11336Start a file with its associated application.
11337
11338When "operation" is not specified or "open", this acts like
11339double-clicking the file in Explorer, or giving the file name as an
11340argument to the DOS "start" command: the file is opened with whatever
11341application (if any) its extension is associated.
11342When another "operation" is given, it specifies what should be done with
11343the file. A typical operation is "print".
11344
11345startfile returns as soon as the associated application is launched.
11346There is no option to wait for the application to close, and no way
11347to retrieve the application's exit status.
11348
11349The filepath is relative to the current directory. If you want to use
11350an absolute path, make sure the first character is not a slash ("/");
11351the underlying Win32 ShellExecute function doesn't work if it is.
11352[clinic start generated code]*/
11353
11354static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011355os_startfile_impl(PyObject *module, path_t *filepath,
11356 const Py_UNICODE *operation)
11357/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011358{
11359 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011360
11361 if(!check_ShellExecute()) {
11362 /* If the OS doesn't have ShellExecute, return a
11363 NotImplementedError. */
11364 return PyErr_Format(PyExc_NotImplementedError,
11365 "startfile not available on this platform");
11366 }
11367
Victor Stinner8c62be82010-05-06 00:08:46 +000011368 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011369 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011370 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011371 Py_END_ALLOW_THREADS
11372
Victor Stinner8c62be82010-05-06 00:08:46 +000011373 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011374 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011375 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 }
Steve Dowercc16be82016-09-08 10:35:16 -070011377 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011378}
Larry Hastings2f936352014-08-05 14:04:04 +100011379#endif /* MS_WINDOWS */
11380
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011381
Martin v. Löwis438b5342002-12-27 10:16:42 +000011382#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011383/*[clinic input]
11384os.getloadavg
11385
11386Return average recent system load information.
11387
11388Return the number of processes in the system run queue averaged over
11389the last 1, 5, and 15 minutes as a tuple of three floats.
11390Raises OSError if the load average was unobtainable.
11391[clinic start generated code]*/
11392
Larry Hastings2f936352014-08-05 14:04:04 +100011393static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011394os_getloadavg_impl(PyObject *module)
11395/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011396{
11397 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011398 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011399 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11400 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011401 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011402 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011403}
Larry Hastings2f936352014-08-05 14:04:04 +100011404#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011405
Larry Hastings2f936352014-08-05 14:04:04 +100011406
11407/*[clinic input]
11408os.device_encoding
11409 fd: int
11410
11411Return a string describing the encoding of a terminal's file descriptor.
11412
11413The file descriptor must be attached to a terminal.
11414If the device is not a terminal, return None.
11415[clinic start generated code]*/
11416
Larry Hastings2f936352014-08-05 14:04:04 +100011417static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011418os_device_encoding_impl(PyObject *module, int fd)
11419/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011420{
Brett Cannonefb00c02012-02-29 18:31:31 -050011421 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011422}
11423
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011424
Larry Hastings2f936352014-08-05 14:04:04 +100011425#ifdef HAVE_SETRESUID
11426/*[clinic input]
11427os.setresuid
11428
11429 ruid: uid_t
11430 euid: uid_t
11431 suid: uid_t
11432 /
11433
11434Set the current process's real, effective, and saved user ids.
11435[clinic start generated code]*/
11436
Larry Hastings2f936352014-08-05 14:04:04 +100011437static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011438os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11439/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011440{
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 if (setresuid(ruid, euid, suid) < 0)
11442 return posix_error();
11443 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011444}
Larry Hastings2f936352014-08-05 14:04:04 +100011445#endif /* HAVE_SETRESUID */
11446
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011447
11448#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011449/*[clinic input]
11450os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011451
Larry Hastings2f936352014-08-05 14:04:04 +100011452 rgid: gid_t
11453 egid: gid_t
11454 sgid: gid_t
11455 /
11456
11457Set the current process's real, effective, and saved group ids.
11458[clinic start generated code]*/
11459
Larry Hastings2f936352014-08-05 14:04:04 +100011460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011461os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
11462/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011463{
Victor Stinner8c62be82010-05-06 00:08:46 +000011464 if (setresgid(rgid, egid, sgid) < 0)
11465 return posix_error();
11466 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011467}
Larry Hastings2f936352014-08-05 14:04:04 +100011468#endif /* HAVE_SETRESGID */
11469
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011470
11471#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100011472/*[clinic input]
11473os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011474
Larry Hastings2f936352014-08-05 14:04:04 +100011475Return a tuple of the current process's real, effective, and saved user ids.
11476[clinic start generated code]*/
11477
Larry Hastings2f936352014-08-05 14:04:04 +100011478static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011479os_getresuid_impl(PyObject *module)
11480/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011481{
Victor Stinner8c62be82010-05-06 00:08:46 +000011482 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 if (getresuid(&ruid, &euid, &suid) < 0)
11484 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011485 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
11486 _PyLong_FromUid(euid),
11487 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011488}
Larry Hastings2f936352014-08-05 14:04:04 +100011489#endif /* HAVE_GETRESUID */
11490
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011491
11492#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100011493/*[clinic input]
11494os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011495
Larry Hastings2f936352014-08-05 14:04:04 +100011496Return a tuple of the current process's real, effective, and saved group ids.
11497[clinic start generated code]*/
11498
Larry Hastings2f936352014-08-05 14:04:04 +100011499static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011500os_getresgid_impl(PyObject *module)
11501/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011502{
11503 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000011504 if (getresgid(&rgid, &egid, &sgid) < 0)
11505 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020011506 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
11507 _PyLong_FromGid(egid),
11508 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011509}
Larry Hastings2f936352014-08-05 14:04:04 +100011510#endif /* HAVE_GETRESGID */
11511
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011512
Benjamin Peterson9428d532011-09-14 11:45:52 -040011513#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100011514/*[clinic input]
11515os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040011516
Larry Hastings2f936352014-08-05 14:04:04 +100011517 path: path_t(allow_fd=True)
11518 attribute: path_t
11519 *
11520 follow_symlinks: bool = True
11521
11522Return the value of extended attribute attribute on path.
11523
BNMetricsb9427072018-11-02 15:20:19 +000011524path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011525If follow_symlinks is False, and the last element of the path is a symbolic
11526 link, getxattr will examine the symbolic link itself instead of the file
11527 the link points to.
11528
11529[clinic start generated code]*/
11530
Larry Hastings2f936352014-08-05 14:04:04 +100011531static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011532os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011533 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011534/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011535{
11536 Py_ssize_t i;
11537 PyObject *buffer = NULL;
11538
11539 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
11540 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011541
Larry Hastings9cf065c2012-06-22 16:30:09 -070011542 for (i = 0; ; i++) {
11543 void *ptr;
11544 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011545 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011546 Py_ssize_t buffer_size = buffer_sizes[i];
11547 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011548 path_error(path);
11549 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011550 }
11551 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11552 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011553 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011554 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011555
Larry Hastings9cf065c2012-06-22 16:30:09 -070011556 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011557 if (path->fd >= 0)
11558 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011559 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011560 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011561 else
Larry Hastings2f936352014-08-05 14:04:04 +100011562 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011563 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011564
Larry Hastings9cf065c2012-06-22 16:30:09 -070011565 if (result < 0) {
11566 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011567 if (errno == ERANGE)
11568 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011569 path_error(path);
11570 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011571 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011572
Larry Hastings9cf065c2012-06-22 16:30:09 -070011573 if (result != buffer_size) {
11574 /* Can only shrink. */
11575 _PyBytes_Resize(&buffer, result);
11576 }
11577 break;
11578 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011579
Larry Hastings9cf065c2012-06-22 16:30:09 -070011580 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011581}
11582
Larry Hastings2f936352014-08-05 14:04:04 +100011583
11584/*[clinic input]
11585os.setxattr
11586
11587 path: path_t(allow_fd=True)
11588 attribute: path_t
11589 value: Py_buffer
11590 flags: int = 0
11591 *
11592 follow_symlinks: bool = True
11593
11594Set extended attribute attribute on path to value.
11595
BNMetricsb9427072018-11-02 15:20:19 +000011596path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011597If follow_symlinks is False, and the last element of the path is a symbolic
11598 link, setxattr will modify the symbolic link itself instead of the file
11599 the link points to.
11600
11601[clinic start generated code]*/
11602
Benjamin Peterson799bd802011-08-31 22:15:17 -040011603static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011604os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011605 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011606/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011607{
Larry Hastings2f936352014-08-05 14:04:04 +100011608 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011609
Larry Hastings2f936352014-08-05 14:04:04 +100011610 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011611 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011612
Benjamin Peterson799bd802011-08-31 22:15:17 -040011613 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011614 if (path->fd > -1)
11615 result = fsetxattr(path->fd, attribute->narrow,
11616 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011617 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011618 result = setxattr(path->narrow, attribute->narrow,
11619 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011620 else
Larry Hastings2f936352014-08-05 14:04:04 +100011621 result = lsetxattr(path->narrow, attribute->narrow,
11622 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011623 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011624
Larry Hastings9cf065c2012-06-22 16:30:09 -070011625 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011626 path_error(path);
11627 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011628 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011629
Larry Hastings2f936352014-08-05 14:04:04 +100011630 Py_RETURN_NONE;
11631}
11632
11633
11634/*[clinic input]
11635os.removexattr
11636
11637 path: path_t(allow_fd=True)
11638 attribute: path_t
11639 *
11640 follow_symlinks: bool = True
11641
11642Remove extended attribute attribute on path.
11643
BNMetricsb9427072018-11-02 15:20:19 +000011644path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011645If follow_symlinks is False, and the last element of the path is a symbolic
11646 link, removexattr will modify the symbolic link itself instead of the file
11647 the link points to.
11648
11649[clinic start generated code]*/
11650
Larry Hastings2f936352014-08-05 14:04:04 +100011651static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011652os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011653 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011654/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011655{
11656 ssize_t result;
11657
11658 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11659 return NULL;
11660
11661 Py_BEGIN_ALLOW_THREADS;
11662 if (path->fd > -1)
11663 result = fremovexattr(path->fd, attribute->narrow);
11664 else if (follow_symlinks)
11665 result = removexattr(path->narrow, attribute->narrow);
11666 else
11667 result = lremovexattr(path->narrow, attribute->narrow);
11668 Py_END_ALLOW_THREADS;
11669
11670 if (result) {
11671 return path_error(path);
11672 }
11673
11674 Py_RETURN_NONE;
11675}
11676
11677
11678/*[clinic input]
11679os.listxattr
11680
11681 path: path_t(allow_fd=True, nullable=True) = None
11682 *
11683 follow_symlinks: bool = True
11684
11685Return a list of extended attributes on path.
11686
BNMetricsb9427072018-11-02 15:20:19 +000011687path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011688if path is None, listxattr will examine the current directory.
11689If follow_symlinks is False, and the last element of the path is a symbolic
11690 link, listxattr will examine the symbolic link itself instead of the file
11691 the link points to.
11692[clinic start generated code]*/
11693
Larry Hastings2f936352014-08-05 14:04:04 +100011694static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011695os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000011696/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011697{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011698 Py_ssize_t i;
11699 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011700 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011701 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011702
Larry Hastings2f936352014-08-05 14:04:04 +100011703 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011704 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011705
Larry Hastings2f936352014-08-05 14:04:04 +100011706 name = path->narrow ? path->narrow : ".";
11707
Larry Hastings9cf065c2012-06-22 16:30:09 -070011708 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011709 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011710 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011711 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011712 Py_ssize_t buffer_size = buffer_sizes[i];
11713 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011714 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011715 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011716 break;
11717 }
11718 buffer = PyMem_MALLOC(buffer_size);
11719 if (!buffer) {
11720 PyErr_NoMemory();
11721 break;
11722 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011723
Larry Hastings9cf065c2012-06-22 16:30:09 -070011724 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011725 if (path->fd > -1)
11726 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011727 else if (follow_symlinks)
11728 length = listxattr(name, buffer, buffer_size);
11729 else
11730 length = llistxattr(name, buffer, buffer_size);
11731 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011732
Larry Hastings9cf065c2012-06-22 16:30:09 -070011733 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011734 if (errno == ERANGE) {
11735 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011736 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011737 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011738 }
Larry Hastings2f936352014-08-05 14:04:04 +100011739 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011740 break;
11741 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011742
Larry Hastings9cf065c2012-06-22 16:30:09 -070011743 result = PyList_New(0);
11744 if (!result) {
11745 goto exit;
11746 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011747
Larry Hastings9cf065c2012-06-22 16:30:09 -070011748 end = buffer + length;
11749 for (trace = start = buffer; trace != end; trace++) {
11750 if (!*trace) {
11751 int error;
11752 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11753 trace - start);
11754 if (!attribute) {
11755 Py_DECREF(result);
11756 result = NULL;
11757 goto exit;
11758 }
11759 error = PyList_Append(result, attribute);
11760 Py_DECREF(attribute);
11761 if (error) {
11762 Py_DECREF(result);
11763 result = NULL;
11764 goto exit;
11765 }
11766 start = trace + 1;
11767 }
11768 }
11769 break;
11770 }
11771exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011772 if (buffer)
11773 PyMem_FREE(buffer);
11774 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011775}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011776#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011777
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011778
Larry Hastings2f936352014-08-05 14:04:04 +100011779/*[clinic input]
11780os.urandom
11781
11782 size: Py_ssize_t
11783 /
11784
11785Return a bytes object containing random bytes suitable for cryptographic use.
11786[clinic start generated code]*/
11787
Larry Hastings2f936352014-08-05 14:04:04 +100011788static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011789os_urandom_impl(PyObject *module, Py_ssize_t size)
11790/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011791{
11792 PyObject *bytes;
11793 int result;
11794
Georg Brandl2fb477c2012-02-21 00:33:36 +010011795 if (size < 0)
11796 return PyErr_Format(PyExc_ValueError,
11797 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011798 bytes = PyBytes_FromStringAndSize(NULL, size);
11799 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011800 return NULL;
11801
Victor Stinnere66987e2016-09-06 16:33:52 -070011802 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011803 if (result == -1) {
11804 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011805 return NULL;
11806 }
Larry Hastings2f936352014-08-05 14:04:04 +100011807 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011808}
11809
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011810/* Terminal size querying */
11811
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011812static PyTypeObject* TerminalSizeType;
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011813
11814PyDoc_STRVAR(TerminalSize_docstring,
11815 "A tuple of (columns, lines) for holding terminal window size");
11816
11817static PyStructSequence_Field TerminalSize_fields[] = {
11818 {"columns", "width of the terminal window in characters"},
11819 {"lines", "height of the terminal window in characters"},
11820 {NULL, NULL}
11821};
11822
11823static PyStructSequence_Desc TerminalSize_desc = {
11824 "os.terminal_size",
11825 TerminalSize_docstring,
11826 TerminalSize_fields,
11827 2,
11828};
11829
11830#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011831/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011832PyDoc_STRVAR(termsize__doc__,
11833 "Return the size of the terminal window as (columns, lines).\n" \
11834 "\n" \
11835 "The optional argument fd (default standard output) specifies\n" \
11836 "which file descriptor should be queried.\n" \
11837 "\n" \
11838 "If the file descriptor is not connected to a terminal, an OSError\n" \
11839 "is thrown.\n" \
11840 "\n" \
11841 "This function will only be defined if an implementation is\n" \
11842 "available for this system.\n" \
11843 "\n" \
oldkaa0735f2018-02-02 16:52:55 +080011844 "shutil.get_terminal_size is the high-level function which should\n" \
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011845 "normally be used, os.get_terminal_size is the low-level implementation.");
11846
11847static PyObject*
11848get_terminal_size(PyObject *self, PyObject *args)
11849{
11850 int columns, lines;
11851 PyObject *termsize;
11852
11853 int fd = fileno(stdout);
11854 /* Under some conditions stdout may not be connected and
11855 * fileno(stdout) may point to an invalid file descriptor. For example
11856 * GUI apps don't have valid standard streams by default.
11857 *
11858 * If this happens, and the optional fd argument is not present,
11859 * the ioctl below will fail returning EBADF. This is what we want.
11860 */
11861
11862 if (!PyArg_ParseTuple(args, "|i", &fd))
11863 return NULL;
11864
11865#ifdef TERMSIZE_USE_IOCTL
11866 {
11867 struct winsize w;
11868 if (ioctl(fd, TIOCGWINSZ, &w))
11869 return PyErr_SetFromErrno(PyExc_OSError);
11870 columns = w.ws_col;
11871 lines = w.ws_row;
11872 }
11873#endif /* TERMSIZE_USE_IOCTL */
11874
11875#ifdef TERMSIZE_USE_CONIO
11876 {
11877 DWORD nhandle;
11878 HANDLE handle;
11879 CONSOLE_SCREEN_BUFFER_INFO csbi;
11880 switch (fd) {
11881 case 0: nhandle = STD_INPUT_HANDLE;
11882 break;
11883 case 1: nhandle = STD_OUTPUT_HANDLE;
11884 break;
11885 case 2: nhandle = STD_ERROR_HANDLE;
11886 break;
11887 default:
11888 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11889 }
11890 handle = GetStdHandle(nhandle);
11891 if (handle == NULL)
11892 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11893 if (handle == INVALID_HANDLE_VALUE)
11894 return PyErr_SetFromWindowsErr(0);
11895
11896 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11897 return PyErr_SetFromWindowsErr(0);
11898
11899 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11900 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11901 }
11902#endif /* TERMSIZE_USE_CONIO */
11903
Eddie Elizondo474eedf2018-11-13 04:09:31 -080011904 termsize = PyStructSequence_New(TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011905 if (termsize == NULL)
11906 return NULL;
11907 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11908 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11909 if (PyErr_Occurred()) {
11910 Py_DECREF(termsize);
11911 return NULL;
11912 }
11913 return termsize;
11914}
11915#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11916
Larry Hastings2f936352014-08-05 14:04:04 +100011917
11918/*[clinic input]
11919os.cpu_count
11920
Charles-François Natali80d62e62015-08-13 20:37:08 +010011921Return the number of CPUs in the system; return None if indeterminable.
11922
11923This number is not equivalent to the number of CPUs the current process can
11924use. The number of usable CPUs can be obtained with
11925``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011926[clinic start generated code]*/
11927
Larry Hastings2f936352014-08-05 14:04:04 +100011928static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011929os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011930/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011931{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011932 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011933#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011934 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11935 Need to fallback to Vista behavior if this call isn't present */
11936 HINSTANCE hKernel32;
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011937 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
Tony Roberts4860f012019-02-02 18:16:42 +010011938 Py_BEGIN_ALLOW_THREADS
11939 hKernel32 = GetModuleHandleW(L"KERNEL32");
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011940 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11941 "GetMaximumProcessorCount");
Tony Roberts4860f012019-02-02 18:16:42 +010011942 Py_END_ALLOW_THREADS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011943 if (_GetMaximumProcessorCount != NULL) {
11944 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11945 }
11946 else {
11947 SYSTEM_INFO sysinfo;
11948 GetSystemInfo(&sysinfo);
11949 ncpu = sysinfo.dwNumberOfProcessors;
11950 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011951#elif defined(__hpux)
11952 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11953#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11954 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011955#elif defined(__DragonFly__) || \
11956 defined(__OpenBSD__) || \
11957 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011958 defined(__NetBSD__) || \
11959 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011960 int mib[2];
11961 size_t len = sizeof(ncpu);
11962 mib[0] = CTL_HW;
11963 mib[1] = HW_NCPU;
11964 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11965 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011966#endif
11967 if (ncpu >= 1)
11968 return PyLong_FromLong(ncpu);
11969 else
11970 Py_RETURN_NONE;
11971}
11972
Victor Stinnerdaf45552013-08-28 00:53:59 +020011973
Larry Hastings2f936352014-08-05 14:04:04 +100011974/*[clinic input]
11975os.get_inheritable -> bool
11976
11977 fd: int
11978 /
11979
11980Get the close-on-exe flag of the specified file descriptor.
11981[clinic start generated code]*/
11982
Larry Hastings2f936352014-08-05 14:04:04 +100011983static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011984os_get_inheritable_impl(PyObject *module, int fd)
11985/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011986{
Steve Dower8fc89802015-04-12 00:26:27 -040011987 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011988 _Py_BEGIN_SUPPRESS_IPH
11989 return_value = _Py_get_inheritable(fd);
11990 _Py_END_SUPPRESS_IPH
11991 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011992}
11993
11994
11995/*[clinic input]
11996os.set_inheritable
11997 fd: int
11998 inheritable: int
11999 /
12000
12001Set the inheritable flag of the specified file descriptor.
12002[clinic start generated code]*/
12003
Larry Hastings2f936352014-08-05 14:04:04 +100012004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012005os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12006/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012007{
Steve Dower8fc89802015-04-12 00:26:27 -040012008 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012009
Steve Dower8fc89802015-04-12 00:26:27 -040012010 _Py_BEGIN_SUPPRESS_IPH
12011 result = _Py_set_inheritable(fd, inheritable, NULL);
12012 _Py_END_SUPPRESS_IPH
12013 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012014 return NULL;
12015 Py_RETURN_NONE;
12016}
12017
12018
12019#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012020/*[clinic input]
12021os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012022 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012023 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012024
Larry Hastings2f936352014-08-05 14:04:04 +100012025Get the close-on-exe flag of the specified file descriptor.
12026[clinic start generated code]*/
12027
Larry Hastings2f936352014-08-05 14:04:04 +100012028static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012029os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012030/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012031{
12032 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012033
12034 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12035 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012036 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012037 }
12038
Larry Hastings2f936352014-08-05 14:04:04 +100012039 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012040}
12041
Victor Stinnerdaf45552013-08-28 00:53:59 +020012042
Larry Hastings2f936352014-08-05 14:04:04 +100012043/*[clinic input]
12044os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012045 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012046 inheritable: bool
12047 /
12048
12049Set the inheritable flag of the specified handle.
12050[clinic start generated code]*/
12051
Larry Hastings2f936352014-08-05 14:04:04 +100012052static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012053os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012054 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012055/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012056{
12057 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012058 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12059 PyErr_SetFromWindowsErr(0);
12060 return NULL;
12061 }
12062 Py_RETURN_NONE;
12063}
Larry Hastings2f936352014-08-05 14:04:04 +100012064#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012065
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012066#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012067/*[clinic input]
12068os.get_blocking -> bool
12069 fd: int
12070 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012071
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012072Get the blocking mode of the file descriptor.
12073
12074Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12075[clinic start generated code]*/
12076
12077static int
12078os_get_blocking_impl(PyObject *module, int fd)
12079/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012080{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012081 int blocking;
12082
Steve Dower8fc89802015-04-12 00:26:27 -040012083 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012084 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012085 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012086 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012087}
12088
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012089/*[clinic input]
12090os.set_blocking
12091 fd: int
12092 blocking: bool(accept={int})
12093 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012094
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012095Set the blocking mode of the specified file descriptor.
12096
12097Set the O_NONBLOCK flag if blocking is False,
12098clear the O_NONBLOCK flag otherwise.
12099[clinic start generated code]*/
12100
12101static PyObject *
12102os_set_blocking_impl(PyObject *module, int fd, int blocking)
12103/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012104{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012105 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012106
Steve Dower8fc89802015-04-12 00:26:27 -040012107 _Py_BEGIN_SUPPRESS_IPH
12108 result = _Py_set_blocking(fd, blocking);
12109 _Py_END_SUPPRESS_IPH
12110 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012111 return NULL;
12112 Py_RETURN_NONE;
12113}
12114#endif /* !MS_WINDOWS */
12115
12116
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012117/*[clinic input]
12118class os.DirEntry "DirEntry *" "&DirEntryType"
12119[clinic start generated code]*/
12120/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012121
12122typedef struct {
12123 PyObject_HEAD
12124 PyObject *name;
12125 PyObject *path;
12126 PyObject *stat;
12127 PyObject *lstat;
12128#ifdef MS_WINDOWS
12129 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012130 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012131 int got_file_index;
12132#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012133#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012134 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012135#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012136 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012137 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012138#endif
12139} DirEntry;
12140
12141static void
12142DirEntry_dealloc(DirEntry *entry)
12143{
12144 Py_XDECREF(entry->name);
12145 Py_XDECREF(entry->path);
12146 Py_XDECREF(entry->stat);
12147 Py_XDECREF(entry->lstat);
12148 Py_TYPE(entry)->tp_free((PyObject *)entry);
12149}
12150
12151/* Forward reference */
12152static int
12153DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12154
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012155/*[clinic input]
12156os.DirEntry.is_symlink -> bool
12157
12158Return True if the entry is a symbolic link; cached per entry.
12159[clinic start generated code]*/
12160
Victor Stinner6036e442015-03-08 01:58:04 +010012161static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012162os_DirEntry_is_symlink_impl(DirEntry *self)
12163/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012164{
12165#ifdef MS_WINDOWS
12166 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012167#elif defined(HAVE_DIRENT_D_TYPE)
12168 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012169 if (self->d_type != DT_UNKNOWN)
12170 return self->d_type == DT_LNK;
12171 else
12172 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012173#else
12174 /* POSIX without d_type */
12175 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012176#endif
12177}
12178
12179static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012180DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12181{
12182 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012183 STRUCT_STAT st;
12184 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012185
12186#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012187 if (!PyUnicode_FSDecoder(self->path, &ub))
12188 return NULL;
12189 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012190#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012191 if (!PyUnicode_FSConverter(self->path, &ub))
12192 return NULL;
12193 const char *path = PyBytes_AS_STRING(ub);
12194 if (self->dir_fd != DEFAULT_DIR_FD) {
12195#ifdef HAVE_FSTATAT
12196 result = fstatat(self->dir_fd, path, &st,
12197 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12198#else
12199 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12200 return NULL;
12201#endif /* HAVE_FSTATAT */
12202 }
12203 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012204#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012205 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012206 if (follow_symlinks)
12207 result = STAT(path, &st);
12208 else
12209 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012210 }
12211 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012212
12213 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012214 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012215
12216 return _pystat_fromstructstat(&st);
12217}
12218
12219static PyObject *
12220DirEntry_get_lstat(DirEntry *self)
12221{
12222 if (!self->lstat) {
12223#ifdef MS_WINDOWS
12224 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
12225#else /* POSIX */
12226 self->lstat = DirEntry_fetch_stat(self, 0);
12227#endif
12228 }
12229 Py_XINCREF(self->lstat);
12230 return self->lstat;
12231}
12232
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012233/*[clinic input]
12234os.DirEntry.stat
12235 *
12236 follow_symlinks: bool = True
12237
12238Return stat_result object for the entry; cached per entry.
12239[clinic start generated code]*/
12240
Victor Stinner6036e442015-03-08 01:58:04 +010012241static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012242os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12243/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012244{
12245 if (!follow_symlinks)
12246 return DirEntry_get_lstat(self);
12247
12248 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012249 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012250 if (result == -1)
12251 return NULL;
12252 else if (result)
12253 self->stat = DirEntry_fetch_stat(self, 1);
12254 else
12255 self->stat = DirEntry_get_lstat(self);
12256 }
12257
12258 Py_XINCREF(self->stat);
12259 return self->stat;
12260}
12261
Victor Stinner6036e442015-03-08 01:58:04 +010012262/* Set exception and return -1 on error, 0 for False, 1 for True */
12263static int
12264DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12265{
12266 PyObject *stat = NULL;
12267 PyObject *st_mode = NULL;
12268 long mode;
12269 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012270#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012271 int is_symlink;
12272 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012273#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012274#ifdef MS_WINDOWS
12275 unsigned long dir_bits;
12276#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010012277 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012278
12279#ifdef MS_WINDOWS
12280 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12281 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012282#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012283 is_symlink = self->d_type == DT_LNK;
12284 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12285#endif
12286
Victor Stinner35a97c02015-03-08 02:59:09 +010012287#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012288 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012289#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012290 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012291 if (!stat) {
12292 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12293 /* If file doesn't exist (anymore), then return False
12294 (i.e., say it's not a file/directory) */
12295 PyErr_Clear();
12296 return 0;
12297 }
12298 goto error;
12299 }
12300 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
12301 if (!st_mode)
12302 goto error;
12303
12304 mode = PyLong_AsLong(st_mode);
12305 if (mode == -1 && PyErr_Occurred())
12306 goto error;
12307 Py_CLEAR(st_mode);
12308 Py_CLEAR(stat);
12309 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012310#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012311 }
12312 else if (is_symlink) {
12313 assert(mode_bits != S_IFLNK);
12314 result = 0;
12315 }
12316 else {
12317 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12318#ifdef MS_WINDOWS
12319 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12320 if (mode_bits == S_IFDIR)
12321 result = dir_bits != 0;
12322 else
12323 result = dir_bits == 0;
12324#else /* POSIX */
12325 if (mode_bits == S_IFDIR)
12326 result = self->d_type == DT_DIR;
12327 else
12328 result = self->d_type == DT_REG;
12329#endif
12330 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012331#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012332
12333 return result;
12334
12335error:
12336 Py_XDECREF(st_mode);
12337 Py_XDECREF(stat);
12338 return -1;
12339}
12340
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012341/*[clinic input]
12342os.DirEntry.is_dir -> bool
12343 *
12344 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012345
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012346Return True if the entry is a directory; cached per entry.
12347[clinic start generated code]*/
12348
12349static int
12350os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12351/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12352{
12353 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012354}
12355
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012356/*[clinic input]
12357os.DirEntry.is_file -> bool
12358 *
12359 follow_symlinks: bool = True
12360
12361Return True if the entry is a file; cached per entry.
12362[clinic start generated code]*/
12363
12364static int
12365os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12366/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012367{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012368 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012369}
12370
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012371/*[clinic input]
12372os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012373
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012374Return inode of the entry; cached per entry.
12375[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012376
12377static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012378os_DirEntry_inode_impl(DirEntry *self)
12379/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012380{
12381#ifdef MS_WINDOWS
12382 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012383 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012384 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012385 STRUCT_STAT stat;
12386 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012387
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012388 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012389 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012390 path = PyUnicode_AsUnicode(unicode);
12391 result = LSTAT(path, &stat);
12392 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012393
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012394 if (result != 0)
12395 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012396
12397 self->win32_file_index = stat.st_ino;
12398 self->got_file_index = 1;
12399 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010012400 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
12401 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010012402#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020012403 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
12404 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010012405#endif
12406}
12407
12408static PyObject *
12409DirEntry_repr(DirEntry *self)
12410{
12411 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
12412}
12413
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012414/*[clinic input]
12415os.DirEntry.__fspath__
12416
12417Returns the path for the entry.
12418[clinic start generated code]*/
12419
Brett Cannon96881cd2016-06-10 14:37:21 -070012420static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012421os_DirEntry___fspath___impl(DirEntry *self)
12422/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070012423{
12424 Py_INCREF(self->path);
12425 return self->path;
12426}
12427
Victor Stinner6036e442015-03-08 01:58:04 +010012428static PyMemberDef DirEntry_members[] = {
12429 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
12430 "the entry's base filename, relative to scandir() \"path\" argument"},
12431 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
12432 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
12433 {NULL}
12434};
12435
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012436#include "clinic/posixmodule.c.h"
12437
Victor Stinner6036e442015-03-08 01:58:04 +010012438static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012439 OS_DIRENTRY_IS_DIR_METHODDEF
12440 OS_DIRENTRY_IS_FILE_METHODDEF
12441 OS_DIRENTRY_IS_SYMLINK_METHODDEF
12442 OS_DIRENTRY_STAT_METHODDEF
12443 OS_DIRENTRY_INODE_METHODDEF
12444 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010012445 {NULL}
12446};
12447
Benjamin Peterson5646de42015-04-12 17:56:34 -040012448static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012449 PyVarObject_HEAD_INIT(NULL, 0)
12450 MODNAME ".DirEntry", /* tp_name */
12451 sizeof(DirEntry), /* tp_basicsize */
12452 0, /* tp_itemsize */
12453 /* methods */
12454 (destructor)DirEntry_dealloc, /* tp_dealloc */
12455 0, /* tp_print */
12456 0, /* tp_getattr */
12457 0, /* tp_setattr */
12458 0, /* tp_compare */
12459 (reprfunc)DirEntry_repr, /* tp_repr */
12460 0, /* tp_as_number */
12461 0, /* tp_as_sequence */
12462 0, /* tp_as_mapping */
12463 0, /* tp_hash */
12464 0, /* tp_call */
12465 0, /* tp_str */
12466 0, /* tp_getattro */
12467 0, /* tp_setattro */
12468 0, /* tp_as_buffer */
12469 Py_TPFLAGS_DEFAULT, /* tp_flags */
12470 0, /* tp_doc */
12471 0, /* tp_traverse */
12472 0, /* tp_clear */
12473 0, /* tp_richcompare */
12474 0, /* tp_weaklistoffset */
12475 0, /* tp_iter */
12476 0, /* tp_iternext */
12477 DirEntry_methods, /* tp_methods */
12478 DirEntry_members, /* tp_members */
12479};
12480
12481#ifdef MS_WINDOWS
12482
12483static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012484join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010012485{
12486 Py_ssize_t path_len;
12487 Py_ssize_t size;
12488 wchar_t *result;
12489 wchar_t ch;
12490
12491 if (!path_wide) { /* Default arg: "." */
12492 path_wide = L".";
12493 path_len = 1;
12494 }
12495 else {
12496 path_len = wcslen(path_wide);
12497 }
12498
12499 /* The +1's are for the path separator and the NUL */
12500 size = path_len + 1 + wcslen(filename) + 1;
12501 result = PyMem_New(wchar_t, size);
12502 if (!result) {
12503 PyErr_NoMemory();
12504 return NULL;
12505 }
12506 wcscpy(result, path_wide);
12507 if (path_len > 0) {
12508 ch = result[path_len - 1];
12509 if (ch != SEP && ch != ALTSEP && ch != L':')
12510 result[path_len++] = SEP;
12511 wcscpy(result + path_len, filename);
12512 }
12513 return result;
12514}
12515
12516static PyObject *
12517DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
12518{
12519 DirEntry *entry;
12520 BY_HANDLE_FILE_INFORMATION file_info;
12521 ULONG reparse_tag;
12522 wchar_t *joined_path;
12523
12524 entry = PyObject_New(DirEntry, &DirEntryType);
12525 if (!entry)
12526 return NULL;
12527 entry->name = NULL;
12528 entry->path = NULL;
12529 entry->stat = NULL;
12530 entry->lstat = NULL;
12531 entry->got_file_index = 0;
12532
12533 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
12534 if (!entry->name)
12535 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012536 if (path->narrow) {
12537 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
12538 if (!entry->name)
12539 goto error;
12540 }
Victor Stinner6036e442015-03-08 01:58:04 +010012541
12542 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
12543 if (!joined_path)
12544 goto error;
12545
12546 entry->path = PyUnicode_FromWideChar(joined_path, -1);
12547 PyMem_Free(joined_path);
12548 if (!entry->path)
12549 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012550 if (path->narrow) {
12551 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12552 if (!entry->path)
12553 goto error;
12554 }
Victor Stinner6036e442015-03-08 01:58:04 +010012555
Steve Dowercc16be82016-09-08 10:35:16 -070012556 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012557 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12558
12559 return (PyObject *)entry;
12560
12561error:
12562 Py_DECREF(entry);
12563 return NULL;
12564}
12565
12566#else /* POSIX */
12567
12568static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012569join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012570{
12571 Py_ssize_t path_len;
12572 Py_ssize_t size;
12573 char *result;
12574
12575 if (!path_narrow) { /* Default arg: "." */
12576 path_narrow = ".";
12577 path_len = 1;
12578 }
12579 else {
12580 path_len = strlen(path_narrow);
12581 }
12582
12583 if (filename_len == -1)
12584 filename_len = strlen(filename);
12585
12586 /* The +1's are for the path separator and the NUL */
12587 size = path_len + 1 + filename_len + 1;
12588 result = PyMem_New(char, size);
12589 if (!result) {
12590 PyErr_NoMemory();
12591 return NULL;
12592 }
12593 strcpy(result, path_narrow);
12594 if (path_len > 0 && result[path_len - 1] != '/')
12595 result[path_len++] = '/';
12596 strcpy(result + path_len, filename);
12597 return result;
12598}
12599
12600static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012601DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012602 ino_t d_ino
12603#ifdef HAVE_DIRENT_D_TYPE
12604 , unsigned char d_type
12605#endif
12606 )
Victor Stinner6036e442015-03-08 01:58:04 +010012607{
12608 DirEntry *entry;
12609 char *joined_path;
12610
12611 entry = PyObject_New(DirEntry, &DirEntryType);
12612 if (!entry)
12613 return NULL;
12614 entry->name = NULL;
12615 entry->path = NULL;
12616 entry->stat = NULL;
12617 entry->lstat = NULL;
12618
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012619 if (path->fd != -1) {
12620 entry->dir_fd = path->fd;
12621 joined_path = NULL;
12622 }
12623 else {
12624 entry->dir_fd = DEFAULT_DIR_FD;
12625 joined_path = join_path_filename(path->narrow, name, name_len);
12626 if (!joined_path)
12627 goto error;
12628 }
Victor Stinner6036e442015-03-08 01:58:04 +010012629
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012630 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012631 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012632 if (joined_path)
12633 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012634 }
12635 else {
12636 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012637 if (joined_path)
12638 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012639 }
12640 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012641 if (!entry->name)
12642 goto error;
12643
12644 if (path->fd != -1) {
12645 entry->path = entry->name;
12646 Py_INCREF(entry->path);
12647 }
12648 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012649 goto error;
12650
Victor Stinner35a97c02015-03-08 02:59:09 +010012651#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012652 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012653#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012654 entry->d_ino = d_ino;
12655
12656 return (PyObject *)entry;
12657
12658error:
12659 Py_XDECREF(entry);
12660 return NULL;
12661}
12662
12663#endif
12664
12665
12666typedef struct {
12667 PyObject_HEAD
12668 path_t path;
12669#ifdef MS_WINDOWS
12670 HANDLE handle;
12671 WIN32_FIND_DATAW file_data;
12672 int first_time;
12673#else /* POSIX */
12674 DIR *dirp;
12675#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012676#ifdef HAVE_FDOPENDIR
12677 int fd;
12678#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012679} ScandirIterator;
12680
12681#ifdef MS_WINDOWS
12682
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012683static int
12684ScandirIterator_is_closed(ScandirIterator *iterator)
12685{
12686 return iterator->handle == INVALID_HANDLE_VALUE;
12687}
12688
Victor Stinner6036e442015-03-08 01:58:04 +010012689static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012690ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012691{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012692 HANDLE handle = iterator->handle;
12693
12694 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012695 return;
12696
Victor Stinner6036e442015-03-08 01:58:04 +010012697 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012698 Py_BEGIN_ALLOW_THREADS
12699 FindClose(handle);
12700 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012701}
12702
12703static PyObject *
12704ScandirIterator_iternext(ScandirIterator *iterator)
12705{
12706 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12707 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012708 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012709
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012710 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012711 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012712 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012713
12714 while (1) {
12715 if (!iterator->first_time) {
12716 Py_BEGIN_ALLOW_THREADS
12717 success = FindNextFileW(iterator->handle, file_data);
12718 Py_END_ALLOW_THREADS
12719 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012720 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012721 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012722 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012723 break;
12724 }
12725 }
12726 iterator->first_time = 0;
12727
12728 /* Skip over . and .. */
12729 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012730 wcscmp(file_data->cFileName, L"..") != 0) {
12731 entry = DirEntry_from_find_data(&iterator->path, file_data);
12732 if (!entry)
12733 break;
12734 return entry;
12735 }
Victor Stinner6036e442015-03-08 01:58:04 +010012736
12737 /* Loop till we get a non-dot directory or finish iterating */
12738 }
12739
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012740 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012741 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012742 return NULL;
12743}
12744
12745#else /* POSIX */
12746
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012747static int
12748ScandirIterator_is_closed(ScandirIterator *iterator)
12749{
12750 return !iterator->dirp;
12751}
12752
Victor Stinner6036e442015-03-08 01:58:04 +010012753static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012754ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012755{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012756 DIR *dirp = iterator->dirp;
12757
12758 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012759 return;
12760
Victor Stinner6036e442015-03-08 01:58:04 +010012761 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012762 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012763#ifdef HAVE_FDOPENDIR
12764 if (iterator->path.fd != -1)
12765 rewinddir(dirp);
12766#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012767 closedir(dirp);
12768 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012769 return;
12770}
12771
12772static PyObject *
12773ScandirIterator_iternext(ScandirIterator *iterator)
12774{
12775 struct dirent *direntp;
12776 Py_ssize_t name_len;
12777 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012778 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012779
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012780 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012781 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012782 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012783
12784 while (1) {
12785 errno = 0;
12786 Py_BEGIN_ALLOW_THREADS
12787 direntp = readdir(iterator->dirp);
12788 Py_END_ALLOW_THREADS
12789
12790 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012791 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012792 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012793 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012794 break;
12795 }
12796
12797 /* Skip over . and .. */
12798 name_len = NAMLEN(direntp);
12799 is_dot = direntp->d_name[0] == '.' &&
12800 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12801 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012802 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012803 name_len, direntp->d_ino
12804#ifdef HAVE_DIRENT_D_TYPE
12805 , direntp->d_type
12806#endif
12807 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012808 if (!entry)
12809 break;
12810 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012811 }
12812
12813 /* Loop till we get a non-dot directory or finish iterating */
12814 }
12815
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012816 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012817 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012818 return NULL;
12819}
12820
12821#endif
12822
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012823static PyObject *
12824ScandirIterator_close(ScandirIterator *self, PyObject *args)
12825{
12826 ScandirIterator_closedir(self);
12827 Py_RETURN_NONE;
12828}
12829
12830static PyObject *
12831ScandirIterator_enter(PyObject *self, PyObject *args)
12832{
12833 Py_INCREF(self);
12834 return self;
12835}
12836
12837static PyObject *
12838ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12839{
12840 ScandirIterator_closedir(self);
12841 Py_RETURN_NONE;
12842}
12843
Victor Stinner6036e442015-03-08 01:58:04 +010012844static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012845ScandirIterator_finalize(ScandirIterator *iterator)
12846{
12847 PyObject *error_type, *error_value, *error_traceback;
12848
12849 /* Save the current exception, if any. */
12850 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12851
12852 if (!ScandirIterator_is_closed(iterator)) {
12853 ScandirIterator_closedir(iterator);
12854
12855 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12856 "unclosed scandir iterator %R", iterator)) {
12857 /* Spurious errors can appear at shutdown */
12858 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12859 PyErr_WriteUnraisable((PyObject *) iterator);
12860 }
12861 }
12862 }
12863
Victor Stinner7bfa4092016-03-23 00:43:54 +010012864 path_cleanup(&iterator->path);
12865
12866 /* Restore the saved exception. */
12867 PyErr_Restore(error_type, error_value, error_traceback);
12868}
12869
12870static void
Victor Stinner6036e442015-03-08 01:58:04 +010012871ScandirIterator_dealloc(ScandirIterator *iterator)
12872{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012873 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12874 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012875
Victor Stinner6036e442015-03-08 01:58:04 +010012876 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12877}
12878
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012879static PyMethodDef ScandirIterator_methods[] = {
12880 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12881 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12882 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12883 {NULL}
12884};
12885
Benjamin Peterson5646de42015-04-12 17:56:34 -040012886static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012887 PyVarObject_HEAD_INIT(NULL, 0)
12888 MODNAME ".ScandirIterator", /* tp_name */
12889 sizeof(ScandirIterator), /* tp_basicsize */
12890 0, /* tp_itemsize */
12891 /* methods */
12892 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12893 0, /* tp_print */
12894 0, /* tp_getattr */
12895 0, /* tp_setattr */
12896 0, /* tp_compare */
12897 0, /* tp_repr */
12898 0, /* tp_as_number */
12899 0, /* tp_as_sequence */
12900 0, /* tp_as_mapping */
12901 0, /* tp_hash */
12902 0, /* tp_call */
12903 0, /* tp_str */
12904 0, /* tp_getattro */
12905 0, /* tp_setattro */
12906 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012907 Py_TPFLAGS_DEFAULT
12908 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012909 0, /* tp_doc */
12910 0, /* tp_traverse */
12911 0, /* tp_clear */
12912 0, /* tp_richcompare */
12913 0, /* tp_weaklistoffset */
12914 PyObject_SelfIter, /* tp_iter */
12915 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012916 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012917 0, /* tp_members */
12918 0, /* tp_getset */
12919 0, /* tp_base */
12920 0, /* tp_dict */
12921 0, /* tp_descr_get */
12922 0, /* tp_descr_set */
12923 0, /* tp_dictoffset */
12924 0, /* tp_init */
12925 0, /* tp_alloc */
12926 0, /* tp_new */
12927 0, /* tp_free */
12928 0, /* tp_is_gc */
12929 0, /* tp_bases */
12930 0, /* tp_mro */
12931 0, /* tp_cache */
12932 0, /* tp_subclasses */
12933 0, /* tp_weaklist */
12934 0, /* tp_del */
12935 0, /* tp_version_tag */
12936 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012937};
12938
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012939/*[clinic input]
12940os.scandir
12941
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012942 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012943
12944Return an iterator of DirEntry objects for given path.
12945
BNMetricsb9427072018-11-02 15:20:19 +000012946path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012947is bytes, the names of yielded DirEntry objects will also be bytes; in
12948all other circumstances they will be str.
12949
12950If path is None, uses the path='.'.
12951[clinic start generated code]*/
12952
Victor Stinner6036e442015-03-08 01:58:04 +010012953static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012954os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000012955/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012956{
12957 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012958#ifdef MS_WINDOWS
12959 wchar_t *path_strW;
12960#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012961 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012962#ifdef HAVE_FDOPENDIR
12963 int fd = -1;
12964#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012965#endif
12966
12967 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12968 if (!iterator)
12969 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012970
12971#ifdef MS_WINDOWS
12972 iterator->handle = INVALID_HANDLE_VALUE;
12973#else
12974 iterator->dirp = NULL;
12975#endif
12976
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012977 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012978 /* Move the ownership to iterator->path */
12979 path->object = NULL;
12980 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012981
12982#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012983 iterator->first_time = 1;
12984
12985 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12986 if (!path_strW)
12987 goto error;
12988
12989 Py_BEGIN_ALLOW_THREADS
12990 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12991 Py_END_ALLOW_THREADS
12992
12993 PyMem_Free(path_strW);
12994
12995 if (iterator->handle == INVALID_HANDLE_VALUE) {
12996 path_error(&iterator->path);
12997 goto error;
12998 }
12999#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013000 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013001#ifdef HAVE_FDOPENDIR
13002 if (path->fd != -1) {
13003 /* closedir() closes the FD, so we duplicate it */
13004 fd = _Py_dup(path->fd);
13005 if (fd == -1)
13006 goto error;
13007
13008 Py_BEGIN_ALLOW_THREADS
13009 iterator->dirp = fdopendir(fd);
13010 Py_END_ALLOW_THREADS
13011 }
13012 else
13013#endif
13014 {
13015 if (iterator->path.narrow)
13016 path_str = iterator->path.narrow;
13017 else
13018 path_str = ".";
13019
13020 Py_BEGIN_ALLOW_THREADS
13021 iterator->dirp = opendir(path_str);
13022 Py_END_ALLOW_THREADS
13023 }
Victor Stinner6036e442015-03-08 01:58:04 +010013024
13025 if (!iterator->dirp) {
13026 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013027#ifdef HAVE_FDOPENDIR
13028 if (fd != -1) {
13029 Py_BEGIN_ALLOW_THREADS
13030 close(fd);
13031 Py_END_ALLOW_THREADS
13032 }
13033#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013034 goto error;
13035 }
13036#endif
13037
13038 return (PyObject *)iterator;
13039
13040error:
13041 Py_DECREF(iterator);
13042 return NULL;
13043}
13044
Ethan Furman410ef8e2016-06-04 12:06:26 -070013045/*
13046 Return the file system path representation of the object.
13047
13048 If the object is str or bytes, then allow it to pass through with
13049 an incremented refcount. If the object defines __fspath__(), then
13050 return the result of that method. All other types raise a TypeError.
13051*/
13052PyObject *
13053PyOS_FSPath(PyObject *path)
13054{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013055 /* For error message reasons, this function is manually inlined in
13056 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013057 _Py_IDENTIFIER(__fspath__);
13058 PyObject *func = NULL;
13059 PyObject *path_repr = NULL;
13060
13061 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13062 Py_INCREF(path);
13063 return path;
13064 }
13065
13066 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13067 if (NULL == func) {
13068 return PyErr_Format(PyExc_TypeError,
13069 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013070 "not %.200s",
13071 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013072 }
13073
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013074 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013075 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013076 if (NULL == path_repr) {
13077 return NULL;
13078 }
13079
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013080 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13081 PyErr_Format(PyExc_TypeError,
13082 "expected %.200s.__fspath__() to return str or bytes, "
13083 "not %.200s", Py_TYPE(path)->tp_name,
13084 Py_TYPE(path_repr)->tp_name);
13085 Py_DECREF(path_repr);
13086 return NULL;
13087 }
13088
Ethan Furman410ef8e2016-06-04 12:06:26 -070013089 return path_repr;
13090}
13091
13092/*[clinic input]
13093os.fspath
13094
13095 path: object
13096
13097Return the file system path representation of the object.
13098
Brett Cannonb4f43e92016-06-09 14:32:08 -070013099If the object is str or bytes, then allow it to pass through as-is. If the
13100object defines __fspath__(), then return the result of that method. All other
13101types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013102[clinic start generated code]*/
13103
13104static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013105os_fspath_impl(PyObject *module, PyObject *path)
13106/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013107{
13108 return PyOS_FSPath(path);
13109}
Victor Stinner6036e442015-03-08 01:58:04 +010013110
Victor Stinner9b1f4742016-09-06 16:18:52 -070013111#ifdef HAVE_GETRANDOM_SYSCALL
13112/*[clinic input]
13113os.getrandom
13114
13115 size: Py_ssize_t
13116 flags: int=0
13117
13118Obtain a series of random bytes.
13119[clinic start generated code]*/
13120
13121static PyObject *
13122os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13123/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13124{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013125 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013126 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013127
13128 if (size < 0) {
13129 errno = EINVAL;
13130 return posix_error();
13131 }
13132
Victor Stinnerec2319c2016-09-20 23:00:59 +020013133 bytes = PyBytes_FromStringAndSize(NULL, size);
13134 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013135 PyErr_NoMemory();
13136 return NULL;
13137 }
13138
13139 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013140 n = syscall(SYS_getrandom,
13141 PyBytes_AS_STRING(bytes),
13142 PyBytes_GET_SIZE(bytes),
13143 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013144 if (n < 0 && errno == EINTR) {
13145 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013146 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013147 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013148
13149 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013150 continue;
13151 }
13152 break;
13153 }
13154
13155 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013156 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013157 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013158 }
13159
Victor Stinnerec2319c2016-09-20 23:00:59 +020013160 if (n != size) {
13161 _PyBytes_Resize(&bytes, n);
13162 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013163
13164 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013165
13166error:
13167 Py_DECREF(bytes);
13168 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013169}
13170#endif /* HAVE_GETRANDOM_SYSCALL */
13171
Steve Dower2438cdf2019-03-29 16:37:16 -070013172#ifdef MS_WINDOWS
13173/* bpo-36085: Helper functions for managing DLL search directories
13174 * on win32
13175 */
13176
13177typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13178typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13179
13180/*[clinic input]
13181os._add_dll_directory
13182
13183 path: path_t
13184
13185Add a path to the DLL search path.
13186
13187This search path is used when resolving dependencies for imported
13188extension modules (the module itself is resolved through sys.path),
13189and also by ctypes.
13190
13191Returns an opaque value that may be passed to os.remove_dll_directory
13192to remove this directory from the search path.
13193[clinic start generated code]*/
13194
13195static PyObject *
13196os__add_dll_directory_impl(PyObject *module, path_t *path)
13197/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13198{
13199 HMODULE hKernel32;
13200 PAddDllDirectory AddDllDirectory;
13201 DLL_DIRECTORY_COOKIE cookie = 0;
13202 DWORD err = 0;
13203
13204 /* For Windows 7, we have to load this. As this will be a fairly
13205 infrequent operation, just do it each time. Kernel32 is always
13206 loaded. */
13207 Py_BEGIN_ALLOW_THREADS
13208 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13209 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13210 hKernel32, "AddDllDirectory")) ||
13211 !(cookie = (*AddDllDirectory)(path->wide))) {
13212 err = GetLastError();
13213 }
13214 Py_END_ALLOW_THREADS
13215
13216 if (err) {
13217 return win32_error_object_err("add_dll_directory",
13218 path->object, err);
13219 }
13220
13221 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13222}
13223
13224/*[clinic input]
13225os._remove_dll_directory
13226
13227 cookie: object
13228
13229Removes a path from the DLL search path.
13230
13231The parameter is an opaque value that was returned from
13232os.add_dll_directory. You can only remove directories that you added
13233yourself.
13234[clinic start generated code]*/
13235
13236static PyObject *
13237os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13238/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13239{
13240 HMODULE hKernel32;
13241 PRemoveDllDirectory RemoveDllDirectory;
13242 DLL_DIRECTORY_COOKIE cookieValue;
13243 DWORD err = 0;
13244
13245 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13246 PyErr_SetString(PyExc_TypeError,
13247 "Provided cookie was not returned from os.add_dll_directory");
13248 return NULL;
13249 }
13250
13251 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13252 cookie, "DLL directory cookie");
13253
13254 /* For Windows 7, we have to load this. As this will be a fairly
13255 infrequent operation, just do it each time. Kernel32 is always
13256 loaded. */
13257 Py_BEGIN_ALLOW_THREADS
13258 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13259 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13260 hKernel32, "RemoveDllDirectory")) ||
13261 !(*RemoveDllDirectory)(cookieValue)) {
13262 err = GetLastError();
13263 }
13264 Py_END_ALLOW_THREADS
13265
13266 if (err) {
13267 return win32_error_object_err("remove_dll_directory",
13268 NULL, err);
13269 }
13270
13271 if (PyCapsule_SetName(cookie, NULL)) {
13272 return NULL;
13273 }
13274
13275 Py_RETURN_NONE;
13276}
13277
13278#endif
Larry Hastings31826802013-10-19 00:09:25 -070013279
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013280static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013281
13282 OS_STAT_METHODDEF
13283 OS_ACCESS_METHODDEF
13284 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013285 OS_CHDIR_METHODDEF
13286 OS_CHFLAGS_METHODDEF
13287 OS_CHMOD_METHODDEF
13288 OS_FCHMOD_METHODDEF
13289 OS_LCHMOD_METHODDEF
13290 OS_CHOWN_METHODDEF
13291 OS_FCHOWN_METHODDEF
13292 OS_LCHOWN_METHODDEF
13293 OS_LCHFLAGS_METHODDEF
13294 OS_CHROOT_METHODDEF
13295 OS_CTERMID_METHODDEF
13296 OS_GETCWD_METHODDEF
13297 OS_GETCWDB_METHODDEF
13298 OS_LINK_METHODDEF
13299 OS_LISTDIR_METHODDEF
13300 OS_LSTAT_METHODDEF
13301 OS_MKDIR_METHODDEF
13302 OS_NICE_METHODDEF
13303 OS_GETPRIORITY_METHODDEF
13304 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013305 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013306 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013307 OS_READLINK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013308 OS_RENAME_METHODDEF
13309 OS_REPLACE_METHODDEF
13310 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013311 OS_SYMLINK_METHODDEF
13312 OS_SYSTEM_METHODDEF
13313 OS_UMASK_METHODDEF
13314 OS_UNAME_METHODDEF
13315 OS_UNLINK_METHODDEF
13316 OS_REMOVE_METHODDEF
13317 OS_UTIME_METHODDEF
13318 OS_TIMES_METHODDEF
13319 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013320 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013321 OS_EXECV_METHODDEF
13322 OS_EXECVE_METHODDEF
13323 OS_SPAWNV_METHODDEF
13324 OS_SPAWNVE_METHODDEF
13325 OS_FORK1_METHODDEF
13326 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020013327 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013328 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
13329 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
13330 OS_SCHED_GETPARAM_METHODDEF
13331 OS_SCHED_GETSCHEDULER_METHODDEF
13332 OS_SCHED_RR_GET_INTERVAL_METHODDEF
13333 OS_SCHED_SETPARAM_METHODDEF
13334 OS_SCHED_SETSCHEDULER_METHODDEF
13335 OS_SCHED_YIELD_METHODDEF
13336 OS_SCHED_SETAFFINITY_METHODDEF
13337 OS_SCHED_GETAFFINITY_METHODDEF
13338 OS_OPENPTY_METHODDEF
13339 OS_FORKPTY_METHODDEF
13340 OS_GETEGID_METHODDEF
13341 OS_GETEUID_METHODDEF
13342 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020013343#ifdef HAVE_GETGROUPLIST
13344 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
13345#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013346 OS_GETGROUPS_METHODDEF
13347 OS_GETPID_METHODDEF
13348 OS_GETPGRP_METHODDEF
13349 OS_GETPPID_METHODDEF
13350 OS_GETUID_METHODDEF
13351 OS_GETLOGIN_METHODDEF
13352 OS_KILL_METHODDEF
13353 OS_KILLPG_METHODDEF
13354 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013355#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070013356 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000013357#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013358 OS_SETUID_METHODDEF
13359 OS_SETEUID_METHODDEF
13360 OS_SETREUID_METHODDEF
13361 OS_SETGID_METHODDEF
13362 OS_SETEGID_METHODDEF
13363 OS_SETREGID_METHODDEF
13364 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000013365#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000013366 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000013367#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100013368 OS_GETPGID_METHODDEF
13369 OS_SETPGRP_METHODDEF
13370 OS_WAIT_METHODDEF
13371 OS_WAIT3_METHODDEF
13372 OS_WAIT4_METHODDEF
13373 OS_WAITID_METHODDEF
13374 OS_WAITPID_METHODDEF
13375 OS_GETSID_METHODDEF
13376 OS_SETSID_METHODDEF
13377 OS_SETPGID_METHODDEF
13378 OS_TCGETPGRP_METHODDEF
13379 OS_TCSETPGRP_METHODDEF
13380 OS_OPEN_METHODDEF
13381 OS_CLOSE_METHODDEF
13382 OS_CLOSERANGE_METHODDEF
13383 OS_DEVICE_ENCODING_METHODDEF
13384 OS_DUP_METHODDEF
13385 OS_DUP2_METHODDEF
13386 OS_LOCKF_METHODDEF
13387 OS_LSEEK_METHODDEF
13388 OS_READ_METHODDEF
13389 OS_READV_METHODDEF
13390 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013391 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013392 OS_WRITE_METHODDEF
13393 OS_WRITEV_METHODDEF
13394 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000013395 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013396#ifdef HAVE_SENDFILE
Serhiy Storchaka62be7422018-11-27 13:27:31 +020013397 {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013398 posix_sendfile__doc__},
13399#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013400 OS_FSTAT_METHODDEF
13401 OS_ISATTY_METHODDEF
13402 OS_PIPE_METHODDEF
13403 OS_PIPE2_METHODDEF
13404 OS_MKFIFO_METHODDEF
13405 OS_MKNOD_METHODDEF
13406 OS_MAJOR_METHODDEF
13407 OS_MINOR_METHODDEF
13408 OS_MAKEDEV_METHODDEF
13409 OS_FTRUNCATE_METHODDEF
13410 OS_TRUNCATE_METHODDEF
13411 OS_POSIX_FALLOCATE_METHODDEF
13412 OS_POSIX_FADVISE_METHODDEF
13413 OS_PUTENV_METHODDEF
13414 OS_UNSETENV_METHODDEF
13415 OS_STRERROR_METHODDEF
13416 OS_FCHDIR_METHODDEF
13417 OS_FSYNC_METHODDEF
13418 OS_SYNC_METHODDEF
13419 OS_FDATASYNC_METHODDEF
13420 OS_WCOREDUMP_METHODDEF
13421 OS_WIFCONTINUED_METHODDEF
13422 OS_WIFSTOPPED_METHODDEF
13423 OS_WIFSIGNALED_METHODDEF
13424 OS_WIFEXITED_METHODDEF
13425 OS_WEXITSTATUS_METHODDEF
13426 OS_WTERMSIG_METHODDEF
13427 OS_WSTOPSIG_METHODDEF
13428 OS_FSTATVFS_METHODDEF
13429 OS_STATVFS_METHODDEF
13430 OS_CONFSTR_METHODDEF
13431 OS_SYSCONF_METHODDEF
13432 OS_FPATHCONF_METHODDEF
13433 OS_PATHCONF_METHODDEF
13434 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030013435 OS__GETFULLPATHNAME_METHODDEF
13436 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013437 OS__GETDISKUSAGE_METHODDEF
13438 OS__GETFINALPATHNAME_METHODDEF
13439 OS__GETVOLUMEPATHNAME_METHODDEF
13440 OS_GETLOADAVG_METHODDEF
13441 OS_URANDOM_METHODDEF
13442 OS_SETRESUID_METHODDEF
13443 OS_SETRESGID_METHODDEF
13444 OS_GETRESUID_METHODDEF
13445 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000013446
Larry Hastings2f936352014-08-05 14:04:04 +100013447 OS_GETXATTR_METHODDEF
13448 OS_SETXATTR_METHODDEF
13449 OS_REMOVEXATTR_METHODDEF
13450 OS_LISTXATTR_METHODDEF
13451
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013452#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
13453 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
13454#endif
Larry Hastings2f936352014-08-05 14:04:04 +100013455 OS_CPU_COUNT_METHODDEF
13456 OS_GET_INHERITABLE_METHODDEF
13457 OS_SET_INHERITABLE_METHODDEF
13458 OS_GET_HANDLE_INHERITABLE_METHODDEF
13459 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013460#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013461 OS_GET_BLOCKING_METHODDEF
13462 OS_SET_BLOCKING_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013463#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013464 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070013465 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070013466 OS_GETRANDOM_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070013467#ifdef MS_WINDOWS
13468 OS__ADD_DLL_DIRECTORY_METHODDEF
13469 OS__REMOVE_DLL_DIRECTORY_METHODDEF
13470#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013471 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000013472};
13473
Barry Warsaw4a342091996-12-19 23:50:02 +000013474static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013475all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000013476{
Guido van Rossum94f6f721999-01-06 18:42:14 +000013477#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013478 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013479#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013480#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013481 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013482#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013483#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013484 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013485#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000013486#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013487 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013488#endif
Fred Drakec9680921999-12-13 16:37:25 +000013489#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013490 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000013491#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013492#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013493 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013494#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013495#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013496 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013497#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013498#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013499 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013500#endif
Fred Drake106c1a02002-04-23 15:58:02 +000013501#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013502 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000013503#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000013504#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013505 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013506#endif
13507#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013508 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013509#endif
13510#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013511 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013512#endif
13513#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013514 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013515#endif
13516#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013517 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013518#endif
13519#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013520 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013521#endif
13522#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013523 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013524#endif
13525#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013526 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013527#endif
13528#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013529 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013530#endif
13531#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013532 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013533#endif
13534#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013535 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013536#endif
13537#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013538 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013539#endif
13540#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013541 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000013542#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000013543#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013544 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013545#endif
13546#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013547 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000013548#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013549#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013550 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013551#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013552#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013553 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013554#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013555#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000013556#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013557 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013558#endif
13559#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013560 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000013561#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020013562#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013563#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013564 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013565#endif
13566#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013567 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013568#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013569#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013570 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050013571#endif
Jesus Ceacf381202012-04-24 20:44:40 +020013572#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013573 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020013574#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020013575#ifdef O_TMPFILE
13576 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
13577#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013578#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013579 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013580#endif
13581#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013582 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013583#endif
13584#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013585 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013586#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020013587#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013588 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020013589#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013590#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013591 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013592#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000013593
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013594
Jesus Cea94363612012-06-22 18:32:07 +020013595#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013596 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013597#endif
13598#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013599 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020013600#endif
13601
Tim Peters5aa91602002-01-30 05:46:57 +000013602/* MS Windows */
13603#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000013604 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013605 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013606#endif
13607#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000013608 /* Optimize for short life (keep in memory). */
13609 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013610 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013611#endif
13612#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000013613 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013614 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013615#endif
13616#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000013617 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013618 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013619#endif
13620#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000013621 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013622 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000013623#endif
13624
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013625/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013626#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013627 /* Send a SIGIO signal whenever input or output
13628 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013629 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013630#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013631#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013632 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013633 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013634#endif
13635#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013636 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013637 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013638#endif
13639#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013640 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013641 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013642#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013643#ifdef O_NOLINKS
13644 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013645 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013646#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013647#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013648 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013649 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013650#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013651
Victor Stinner8c62be82010-05-06 00:08:46 +000013652 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013653#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013654 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013655#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013656#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013657 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013658#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013659#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013660 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013661#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013662#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013663 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013664#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013665#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013666 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013667#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013668#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013669 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013670#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013671#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013672 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013673#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013674#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013675 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013676#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013677#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013678 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013679#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013680#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013681 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013682#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013683#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013684 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013685#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013686#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013687 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013688#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013689#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013690 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013691#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013692#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013693 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013694#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013695#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013696 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013697#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013698#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013699 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013700#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013701#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013702 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013703#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013704
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013705 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013706#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013707 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013708#endif /* ST_RDONLY */
13709#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013710 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013711#endif /* ST_NOSUID */
13712
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013713 /* GNU extensions */
13714#ifdef ST_NODEV
13715 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13716#endif /* ST_NODEV */
13717#ifdef ST_NOEXEC
13718 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13719#endif /* ST_NOEXEC */
13720#ifdef ST_SYNCHRONOUS
13721 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13722#endif /* ST_SYNCHRONOUS */
13723#ifdef ST_MANDLOCK
13724 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13725#endif /* ST_MANDLOCK */
13726#ifdef ST_WRITE
13727 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13728#endif /* ST_WRITE */
13729#ifdef ST_APPEND
13730 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13731#endif /* ST_APPEND */
13732#ifdef ST_NOATIME
13733 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13734#endif /* ST_NOATIME */
13735#ifdef ST_NODIRATIME
13736 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13737#endif /* ST_NODIRATIME */
13738#ifdef ST_RELATIME
13739 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13740#endif /* ST_RELATIME */
13741
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013742 /* FreeBSD sendfile() constants */
13743#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013744 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013745#endif
13746#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013747 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013748#endif
13749#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013750 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013751#endif
13752
Ross Lagerwall7807c352011-03-17 20:20:30 +020013753 /* constants for posix_fadvise */
13754#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013755 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013756#endif
13757#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013758 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013759#endif
13760#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013761 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013762#endif
13763#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013764 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013765#endif
13766#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013767 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013768#endif
13769#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013770 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013771#endif
13772
13773 /* constants for waitid */
13774#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013775 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13776 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13777 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013778#endif
13779#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013780 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013781#endif
13782#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013783 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013784#endif
13785#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013786 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013787#endif
13788#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013789 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013790#endif
13791#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013792 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013793#endif
13794#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013795 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013796#endif
13797#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013798 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013799#endif
13800
13801 /* constants for lockf */
13802#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013803 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013804#endif
13805#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013806 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013807#endif
13808#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013809 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013810#endif
13811#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013812 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013813#endif
13814
Pablo Galindo4defba32018-01-27 16:16:37 +000013815#ifdef RWF_DSYNC
13816 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13817#endif
13818#ifdef RWF_HIPRI
13819 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13820#endif
13821#ifdef RWF_SYNC
13822 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13823#endif
13824#ifdef RWF_NOWAIT
13825 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13826#endif
13827
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013828/* constants for posix_spawn */
13829#ifdef HAVE_POSIX_SPAWN
13830 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
13831 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
13832 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
13833#endif
13834
Guido van Rossum246bc171999-02-01 23:54:31 +000013835#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013836 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13837 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13838 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13839 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13840 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013841#endif
13842
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013843#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013844#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013845 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013846#endif
13847#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013848 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013849#endif
13850#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013851 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013852#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013853#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013854 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013855#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013856#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013857 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013858#endif
13859#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013860 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013861#endif
13862#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013863 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013864#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013865#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013866 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013867#endif
13868#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013869 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013870#endif
13871#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013872 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013873#endif
13874#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013875 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013876#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013877#endif
13878
Benjamin Peterson9428d532011-09-14 11:45:52 -040013879#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013880 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13881 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13882 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013883#endif
13884
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013885#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013886 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013887#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013888#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013889 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013890#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013891#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013892 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013893#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013894#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013895 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013896#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013897#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013898 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013899#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013900#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013901 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013902#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013903#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013904 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013905#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013906#if HAVE_DECL_RTLD_MEMBER
13907 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13908#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013909
Victor Stinner9b1f4742016-09-06 16:18:52 -070013910#ifdef HAVE_GETRANDOM_SYSCALL
13911 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13912 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13913#endif
13914
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013915#if defined(__APPLE__)
13916 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
13917#endif
13918
Steve Dower2438cdf2019-03-29 16:37:16 -070013919#ifdef MS_WINDOWS
13920 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
13921 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
13922 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
13923 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
13924 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
13925#endif
13926
Victor Stinner8c62be82010-05-06 00:08:46 +000013927 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013928}
13929
13930
Martin v. Löwis1a214512008-06-11 05:26:20 +000013931static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013932 PyModuleDef_HEAD_INIT,
13933 MODNAME,
13934 posix__doc__,
13935 -1,
13936 posix_methods,
13937 NULL,
13938 NULL,
13939 NULL,
13940 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013941};
13942
13943
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013944static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013945
13946#ifdef HAVE_FACCESSAT
13947 "HAVE_FACCESSAT",
13948#endif
13949
13950#ifdef HAVE_FCHDIR
13951 "HAVE_FCHDIR",
13952#endif
13953
13954#ifdef HAVE_FCHMOD
13955 "HAVE_FCHMOD",
13956#endif
13957
13958#ifdef HAVE_FCHMODAT
13959 "HAVE_FCHMODAT",
13960#endif
13961
13962#ifdef HAVE_FCHOWN
13963 "HAVE_FCHOWN",
13964#endif
13965
Larry Hastings00964ed2013-08-12 13:49:30 -040013966#ifdef HAVE_FCHOWNAT
13967 "HAVE_FCHOWNAT",
13968#endif
13969
Larry Hastings9cf065c2012-06-22 16:30:09 -070013970#ifdef HAVE_FEXECVE
13971 "HAVE_FEXECVE",
13972#endif
13973
13974#ifdef HAVE_FDOPENDIR
13975 "HAVE_FDOPENDIR",
13976#endif
13977
Georg Brandl306336b2012-06-24 12:55:33 +020013978#ifdef HAVE_FPATHCONF
13979 "HAVE_FPATHCONF",
13980#endif
13981
Larry Hastings9cf065c2012-06-22 16:30:09 -070013982#ifdef HAVE_FSTATAT
13983 "HAVE_FSTATAT",
13984#endif
13985
13986#ifdef HAVE_FSTATVFS
13987 "HAVE_FSTATVFS",
13988#endif
13989
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013990#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013991 "HAVE_FTRUNCATE",
13992#endif
13993
Larry Hastings9cf065c2012-06-22 16:30:09 -070013994#ifdef HAVE_FUTIMENS
13995 "HAVE_FUTIMENS",
13996#endif
13997
13998#ifdef HAVE_FUTIMES
13999 "HAVE_FUTIMES",
14000#endif
14001
14002#ifdef HAVE_FUTIMESAT
14003 "HAVE_FUTIMESAT",
14004#endif
14005
14006#ifdef HAVE_LINKAT
14007 "HAVE_LINKAT",
14008#endif
14009
14010#ifdef HAVE_LCHFLAGS
14011 "HAVE_LCHFLAGS",
14012#endif
14013
14014#ifdef HAVE_LCHMOD
14015 "HAVE_LCHMOD",
14016#endif
14017
14018#ifdef HAVE_LCHOWN
14019 "HAVE_LCHOWN",
14020#endif
14021
14022#ifdef HAVE_LSTAT
14023 "HAVE_LSTAT",
14024#endif
14025
14026#ifdef HAVE_LUTIMES
14027 "HAVE_LUTIMES",
14028#endif
14029
14030#ifdef HAVE_MKDIRAT
14031 "HAVE_MKDIRAT",
14032#endif
14033
14034#ifdef HAVE_MKFIFOAT
14035 "HAVE_MKFIFOAT",
14036#endif
14037
14038#ifdef HAVE_MKNODAT
14039 "HAVE_MKNODAT",
14040#endif
14041
14042#ifdef HAVE_OPENAT
14043 "HAVE_OPENAT",
14044#endif
14045
14046#ifdef HAVE_READLINKAT
14047 "HAVE_READLINKAT",
14048#endif
14049
14050#ifdef HAVE_RENAMEAT
14051 "HAVE_RENAMEAT",
14052#endif
14053
14054#ifdef HAVE_SYMLINKAT
14055 "HAVE_SYMLINKAT",
14056#endif
14057
14058#ifdef HAVE_UNLINKAT
14059 "HAVE_UNLINKAT",
14060#endif
14061
14062#ifdef HAVE_UTIMENSAT
14063 "HAVE_UTIMENSAT",
14064#endif
14065
14066#ifdef MS_WINDOWS
14067 "MS_WINDOWS",
14068#endif
14069
14070 NULL
14071};
14072
14073
Mark Hammondfe51c6d2002-08-02 02:27:13 +000014074PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000014075INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014076{
Victor Stinner8c62be82010-05-06 00:08:46 +000014077 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014078 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014079 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014080
Victor Stinner8c62be82010-05-06 00:08:46 +000014081 m = PyModule_Create(&posixmodule);
14082 if (m == NULL)
14083 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000014084
Victor Stinner8c62be82010-05-06 00:08:46 +000014085 /* Initialize environ dictionary */
14086 v = convertenviron();
14087 Py_XINCREF(v);
14088 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
14089 return NULL;
14090 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014091
Victor Stinner8c62be82010-05-06 00:08:46 +000014092 if (all_ins(m))
14093 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000014094
Victor Stinner8c62be82010-05-06 00:08:46 +000014095 if (setup_confname_tables(m))
14096 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000014097
Victor Stinner8c62be82010-05-06 00:08:46 +000014098 Py_INCREF(PyExc_OSError);
14099 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014100
Guido van Rossumb3d39562000-01-31 18:41:26 +000014101#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000014102 if (posix_putenv_garbage == NULL)
14103 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000014104#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000014105
Victor Stinner8c62be82010-05-06 00:08:46 +000014106 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020014107#if defined(HAVE_WAITID) && !defined(__APPLE__)
14108 waitid_result_desc.name = MODNAME ".waitid_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014109 WaitidResultType = PyStructSequence_NewType(&waitid_result_desc);
14110 if (WaitidResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014111 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014112 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014113#endif
14114
Christian Heimes25827622013-10-12 01:27:08 +020014115 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000014116 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14117 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14118 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014119 StatResultType = PyStructSequence_NewType(&stat_result_desc);
14120 if (StatResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014121 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014122 }
14123 structseq_new = StatResultType->tp_new;
14124 StatResultType->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014125
Christian Heimes25827622013-10-12 01:27:08 +020014126 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014127 StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc);
14128 if (StatVFSResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014129 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014130 }
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014131#ifdef NEED_TICKS_PER_SECOND
14132# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000014133 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014134# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000014135 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014136# else
Victor Stinner8c62be82010-05-06 00:08:46 +000014137 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014138# endif
14139#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014140
William Orr81574b82018-10-01 22:19:56 -070014141#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014142 sched_param_desc.name = MODNAME ".sched_param";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014143 SchedParamType = PyStructSequence_NewType(&sched_param_desc);
14144 if (SchedParamType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014145 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014146 }
14147 SchedParamType->tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014148#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014149
14150 /* initialize TerminalSize_info */
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014151 TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc);
14152 if (TerminalSizeType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014153 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014154 }
Victor Stinner6036e442015-03-08 01:58:04 +010014155
14156 /* initialize scandir types */
14157 if (PyType_Ready(&ScandirIteratorType) < 0)
14158 return NULL;
14159 if (PyType_Ready(&DirEntryType) < 0)
14160 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000014161 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020014162#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014163 Py_INCREF((PyObject*) WaitidResultType);
14164 PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +020014165#endif
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014166 Py_INCREF((PyObject*) StatResultType);
14167 PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType);
14168 Py_INCREF((PyObject*) StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000014169 PyModule_AddObject(m, "statvfs_result",
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014170 (PyObject*) StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014171
14172#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014173 Py_INCREF(SchedParamType);
14174 PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014175#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014176
Larry Hastings605a62d2012-06-24 04:33:36 -070014177 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014178 TimesResultType = PyStructSequence_NewType(&times_result_desc);
14179 if (TimesResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014180 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014181 }
14182 PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014183
14184 uname_result_desc.name = MODNAME ".uname_result";
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014185 UnameResultType = PyStructSequence_NewType(&uname_result_desc);
14186 if (UnameResultType == NULL) {
Victor Stinner1c8f0592013-07-22 22:24:54 +020014187 return NULL;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014188 }
14189 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -070014190
Thomas Wouters477c8d52006-05-27 19:21:47 +000014191#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014192 /*
14193 * Step 2 of weak-linking support on Mac OS X.
14194 *
14195 * The code below removes functions that are not available on the
14196 * currently active platform.
14197 *
14198 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014199 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014200 * OSX 10.4.
14201 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014202#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014203 if (fstatvfs == NULL) {
14204 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
14205 return NULL;
14206 }
14207 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014208#endif /* HAVE_FSTATVFS */
14209
14210#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014211 if (statvfs == NULL) {
14212 if (PyObject_DelAttrString(m, "statvfs") == -1) {
14213 return NULL;
14214 }
14215 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014216#endif /* HAVE_STATVFS */
14217
14218# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014219 if (lchown == NULL) {
14220 if (PyObject_DelAttrString(m, "lchown") == -1) {
14221 return NULL;
14222 }
14223 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014224#endif /* HAVE_LCHOWN */
14225
14226
14227#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014228
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014229 Py_INCREF(TerminalSizeType);
14230 PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014231
Larry Hastings6fe20b32012-04-19 15:07:49 -070014232 billion = PyLong_FromLong(1000000000);
14233 if (!billion)
14234 return NULL;
14235
Larry Hastings9cf065c2012-06-22 16:30:09 -070014236 /* suppress "function not used" warnings */
14237 {
14238 int ignored;
14239 fd_specified("", -1);
14240 follow_symlinks_specified("", 1);
14241 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14242 dir_fd_converter(Py_None, &ignored);
14243 dir_fd_unavailable(Py_None, &ignored);
14244 }
14245
14246 /*
14247 * provide list of locally available functions
14248 * so os.py can populate support_* lists
14249 */
14250 list = PyList_New(0);
14251 if (!list)
14252 return NULL;
14253 for (trace = have_functions; *trace; trace++) {
14254 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14255 if (!unicode)
14256 return NULL;
14257 if (PyList_Append(list, unicode))
14258 return NULL;
14259 Py_DECREF(unicode);
14260 }
14261 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014262
14263 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070014264 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070014265
14266 initialized = 1;
14267
Victor Stinner8c62be82010-05-06 00:08:46 +000014268 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000014269}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014270
14271#ifdef __cplusplus
14272}
14273#endif