blob: 60a60e9aed76b623fcb49e4e3681a005cf0e34c4 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* POSIX module implementation */
2
Jesus Ceaab70e2a2012-10-05 01:48:08 +02003/* This file is also used for Windows NT/MS-Win. In that case the
4 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00007 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02008 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +00009
Thomas Wouters477c8d52006-05-27 19:21:47 +000010#ifdef __APPLE__
11 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000012 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000013 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
14 * at the end of this file for more information.
15 */
16# pragma weak lchown
17# pragma weak statvfs
18# pragma weak fstatvfs
19
20#endif /* __APPLE__ */
21
Thomas Wouters68bc4f92006-03-01 01:05:10 +000022#define PY_SSIZE_T_CLEAN
23
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000024#include "Python.h"
Victor Stinnerd5d9e812019-05-13 12:35:37 +020025#ifdef MS_WINDOWS
26 /* include <windows.h> early to avoid conflict with pycore_condvar.h:
27
28 #define WIN32_LEAN_AND_MEAN
29 #include <windows.h>
30
31 FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
32# include <windows.h>
33#endif
34
Victor Stinner4a21e572020-04-15 02:35:41 +020035#include "pycore_ceval.h" // _PyEval_ReInitThreads()
36#include "pycore_import.h" // _PyImport_ReInitLock()
37#include "pycore_pystate.h" // _PyInterpreterState_GET()
38#include "structmember.h" // PyMemberDef
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020039#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020040# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010041#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020042# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020043#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000044
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020045/* On android API level 21, 'AT_EACCESS' is not declared although
46 * HAVE_FACCESSAT is defined. */
47#ifdef __ANDROID__
Victor Stinner5eca75d2020-04-15 15:07:31 +020048# undef HAVE_FACCESSAT
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020049#endif
50
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000051#include <stdio.h> /* needed for ctermid() */
52
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000053#ifdef __cplusplus
54extern "C" {
55#endif
56
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000057PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000058"This module provides access to operating system functionality that is\n\
59standardized by the C Standard and the POSIX standard (a thinly\n\
60disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000061corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000062
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000063
Ross Lagerwall4d076da2011-03-18 06:56:53 +020064#ifdef HAVE_SYS_UIO_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020065# include <sys/uio.h>
Ross Lagerwall4d076da2011-03-18 06:56:53 +020066#endif
67
Christian Heimes75b96182017-09-05 15:53:09 +020068#ifdef HAVE_SYS_SYSMACROS_H
69/* GNU C Library: major(), minor(), makedev() */
Victor Stinner5eca75d2020-04-15 15:07:31 +020070# include <sys/sysmacros.h>
Christian Heimes75b96182017-09-05 15:53:09 +020071#endif
72
Thomas Wouters0e3f5912006-08-11 14:57:12 +000073#ifdef HAVE_SYS_TYPES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020074# include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#endif /* HAVE_SYS_TYPES_H */
76
77#ifdef HAVE_SYS_STAT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020078# include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000079#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000080
Guido van Rossum36bc6801995-06-14 22:54:23 +000081#ifdef HAVE_SYS_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020082# include <sys/wait.h> // WNOHANG
Guido van Rossum36bc6801995-06-14 22:54:23 +000083#endif
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080084#ifdef HAVE_LINUX_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020085# include <linux/wait.h> // P_PIDFD
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080086#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000087
Thomas Wouters0e3f5912006-08-11 14:57:12 +000088#ifdef HAVE_SIGNAL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020089# include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000090#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000091
Guido van Rossumb6775db1994-08-01 11:34:53 +000092#ifdef HAVE_FCNTL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020093# include <fcntl.h>
94#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000095
Guido van Rossuma6535fd2001-10-18 19:44:10 +000096#ifdef HAVE_GRP_H
Victor Stinner5eca75d2020-04-15 15:07:31 +020097# include <grp.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000098#endif
99
Barry Warsaw5676bd12003-01-07 20:57:09 +0000100#ifdef HAVE_SYSEXITS_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200101# include <sysexits.h>
102#endif
Barry Warsaw5676bd12003-01-07 20:57:09 +0000103
Anthony Baxter8a560de2004-10-13 15:30:56 +0000104#ifdef HAVE_SYS_LOADAVG_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200105# include <sys/loadavg.h>
Anthony Baxter8a560de2004-10-13 15:30:56 +0000106#endif
107
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000108#ifdef HAVE_SYS_SENDFILE_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200109# include <sys/sendfile.h>
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000110#endif
111
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200112#if defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200113# include <copyfile.h>
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200114#endif
115
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500116#ifdef HAVE_SCHED_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200117# include <sched.h>
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500118#endif
119
Pablo Galindoaac4d032019-05-31 19:39:47 +0100120#ifdef HAVE_COPY_FILE_RANGE
Victor Stinner5eca75d2020-04-15 15:07:31 +0200121# include <unistd.h>
Pablo Galindoaac4d032019-05-31 19:39:47 +0100122#endif
123
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500124#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200125# undef HAVE_SCHED_SETAFFINITY
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500126#endif
127
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200128#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200129# define USE_XATTRS
Benjamin Peterson9428d532011-09-14 11:45:52 -0400130#endif
131
132#ifdef USE_XATTRS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200133# include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400134#endif
135
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000136#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200137# ifdef HAVE_SYS_SOCKET_H
138# include <sys/socket.h>
139# endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000140#endif
141
Victor Stinner8b905bd2011-10-25 13:34:04 +0200142#ifdef HAVE_DLFCN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200143# include <dlfcn.h>
Victor Stinner8b905bd2011-10-25 13:34:04 +0200144#endif
145
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200146#ifdef __hpux
Victor Stinner5eca75d2020-04-15 15:07:31 +0200147# include <sys/mpctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200148#endif
149
150#if defined(__DragonFly__) || \
151 defined(__OpenBSD__) || \
152 defined(__FreeBSD__) || \
153 defined(__NetBSD__) || \
154 defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200155# include <sys/sysctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200156#endif
157
Victor Stinner9b1f4742016-09-06 16:18:52 -0700158#ifdef HAVE_LINUX_RANDOM_H
159# include <linux/random.h>
160#endif
161#ifdef HAVE_GETRANDOM_SYSCALL
162# include <sys/syscall.h>
163#endif
164
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100165#if defined(MS_WINDOWS)
166# define TERMSIZE_USE_CONIO
167#elif defined(HAVE_SYS_IOCTL_H)
168# include <sys/ioctl.h>
169# if defined(HAVE_TERMIOS_H)
170# include <termios.h>
171# endif
172# if defined(TIOCGWINSZ)
173# define TERMSIZE_USE_IOCTL
174# endif
175#endif /* MS_WINDOWS */
176
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000178/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000179#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200180# define HAVE_OPENDIR 1
181# define HAVE_SYSTEM 1
182# include <process.h>
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000183#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200184# ifdef _MSC_VER
185 /* Microsoft compiler */
186# define HAVE_GETPPID 1
187# define HAVE_GETLOGIN 1
188# define HAVE_SPAWNV 1
189# define HAVE_EXECV 1
190# define HAVE_WSPAWNV 1
191# define HAVE_WEXECV 1
192# define HAVE_PIPE 1
193# define HAVE_SYSTEM 1
194# define HAVE_CWAIT 1
195# define HAVE_FSYNC 1
196# define fsync _commit
197# else
198 /* Unix functions that the configure script doesn't check for */
199# ifndef __VXWORKS__
200# define HAVE_EXECV 1
201# define HAVE_FORK 1
202# if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
203# define HAVE_FORK1 1
204# endif
205# endif
206# define HAVE_GETEGID 1
207# define HAVE_GETEUID 1
208# define HAVE_GETGID 1
209# define HAVE_GETPPID 1
210# define HAVE_GETUID 1
211# define HAVE_KILL 1
212# define HAVE_OPENDIR 1
213# define HAVE_PIPE 1
214# define HAVE_SYSTEM 1
215# define HAVE_WAIT 1
216# define HAVE_TTYNAME 1
217# endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000218#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000219
Eddie Elizondob3966632019-11-05 07:16:14 -0800220_Py_IDENTIFIER(__fspath__);
Victor Stinnera2f7c002012-02-08 03:36:25 +0100221
Larry Hastings61272b72014-01-07 12:41:53 -0800222/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000223# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800224module os
Larry Hastings61272b72014-01-07 12:41:53 -0800225[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000226/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100227
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000229
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000230#if defined(__sgi)&&_COMPILER_VERSION>=700
231/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
232 (default) */
233extern char *ctermid_r(char *);
234#endif
235
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237
pxinwrf2d7ac72019-05-21 18:46:37 +0800238#if defined(__VXWORKS__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200239# include <vxCpuLib.h>
240# include <rtpLib.h>
241# include <wait.h>
242# include <taskLib.h>
243# ifndef _P_WAIT
244# define _P_WAIT 0
245# define _P_NOWAIT 1
246# define _P_NOWAITO 1
247# endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800248#endif /* __VXWORKS__ */
249
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000250#ifdef HAVE_POSIX_SPAWN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200251# include <spawn.h>
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000252#endif
253
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254#ifdef HAVE_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200255# include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000256#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000258#ifdef HAVE_SYS_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200259# include <sys/utime.h>
260# define HAVE_UTIME_H /* pretend we do for the rest of this file */
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000261#endif /* HAVE_SYS_UTIME_H */
262
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#ifdef HAVE_SYS_TIMES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200264# include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000265#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266
267#ifdef HAVE_SYS_PARAM_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200268# include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000269#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270
271#ifdef HAVE_SYS_UTSNAME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200272# include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000275#ifdef HAVE_DIRENT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200276# include <dirent.h>
277# define NAMLEN(dirent) strlen((dirent)->d_name)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200279# if defined(__WATCOMC__) && !defined(__QNX__)
280# include <direct.h>
281# define NAMLEN(dirent) strlen((dirent)->d_name)
282# else
283# define dirent direct
284# define NAMLEN(dirent) (dirent)->d_namlen
285# endif
286# ifdef HAVE_SYS_NDIR_H
287# include <sys/ndir.h>
288# endif
289# ifdef HAVE_SYS_DIR_H
290# include <sys/dir.h>
291# endif
292# ifdef HAVE_NDIR_H
293# include <ndir.h>
294# endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000295#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000297#ifdef _MSC_VER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200298# ifdef HAVE_DIRECT_H
299# include <direct.h>
300# endif
301# ifdef HAVE_IO_H
302# include <io.h>
303# endif
304# ifdef HAVE_PROCESS_H
305# include <process.h>
306# endif
307# ifndef IO_REPARSE_TAG_SYMLINK
308# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
309# endif
310# ifndef IO_REPARSE_TAG_MOUNT_POINT
311# define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
312# endif
313# include "osdefs.h" // SEP
314# include <malloc.h>
315# include <windows.h>
316# include <shellapi.h> // ShellExecute()
317# include <lmcons.h> // UNLEN
318# define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000319#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000320
Tim Petersbc2e10e2002-03-03 23:17:02 +0000321#ifndef MAXPATHLEN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200322# if defined(PATH_MAX) && PATH_MAX > 1024
323# define MAXPATHLEN PATH_MAX
324# else
325# define MAXPATHLEN 1024
326# endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#endif /* MAXPATHLEN */
328
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000329#ifdef UNION_WAIT
Victor Stinner5eca75d2020-04-15 15:07:31 +0200330 /* Emulate some macros on systems that have a union instead of macros */
331# ifndef WIFEXITED
332# define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
333# endif
334# ifndef WEXITSTATUS
335# define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
336# endif
337# ifndef WTERMSIG
338# define WTERMSIG(u_wait) ((u_wait).w_termsig)
339# endif
340# define WAIT_TYPE union wait
341# define WAIT_STATUS_INT(s) (s.w_status)
342#else
343 /* !UNION_WAIT */
344# define WAIT_TYPE int
345# define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000346#endif /* UNION_WAIT */
347
Greg Wardb48bc172000-03-01 21:51:56 +0000348/* Don't use the "_r" form if we don't need it (also, won't have a
349 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200350#if defined(HAVE_CTERMID_R)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200351# define USE_CTERMID_R
Greg Wardb48bc172000-03-01 21:51:56 +0000352#endif
353
Fred Drake699f3522000-06-29 21:12:41 +0000354/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000355#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000356#undef FSTAT
357#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200358#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200359# define STAT win32_stat
360# define LSTAT win32_lstat
361# define FSTAT _Py_fstat_noraise
362# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000363#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200364# define STAT stat
365# define LSTAT lstat
366# define FSTAT fstat
367# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000368#endif
369
Tim Peters11b23062003-04-23 02:39:17 +0000370#if defined(MAJOR_IN_MKDEV)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200371# include <sys/mkdev.h>
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000372#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200373# if defined(MAJOR_IN_SYSMACROS)
374# include <sys/sysmacros.h>
375# endif
376# if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
377# include <sys/mkdev.h>
378# endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000379#endif
Fred Drake699f3522000-06-29 21:12:41 +0000380
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200381#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200382# define INITFUNC PyInit_nt
383# define MODNAME "nt"
Victor Stinner6036e442015-03-08 01:58:04 +0100384#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200385# define INITFUNC PyInit_posix
386# define MODNAME "posix"
Victor Stinner6036e442015-03-08 01:58:04 +0100387#endif
388
jcea6c51d512018-01-28 14:00:08 +0100389#if defined(__sun)
390/* Something to implement in autoconf, not present in autoconf 2.69 */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200391# define HAVE_STRUCT_STAT_ST_FSTYPE 1
jcea6c51d512018-01-28 14:00:08 +0100392#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200393
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600394/* memfd_create is either defined in sys/mman.h or sys/memfd.h
395 * linux/memfd.h defines additional flags
396 */
397#ifdef HAVE_SYS_MMAN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200398# include <sys/mman.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600399#endif
400#ifdef HAVE_SYS_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200401# include <sys/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600402#endif
403#ifdef HAVE_LINUX_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200404# include <linux/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600405#endif
406
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800407#ifdef _Py_MEMORY_SANITIZER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200408# include <sanitizer/msan_interface.h>
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800409#endif
410
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200411#ifdef HAVE_FORK
412static void
413run_at_forkers(PyObject *lst, int reverse)
414{
415 Py_ssize_t i;
416 PyObject *cpy;
417
418 if (lst != NULL) {
419 assert(PyList_CheckExact(lst));
420
421 /* Use a list copy in case register_at_fork() is called from
422 * one of the callbacks.
423 */
424 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
425 if (cpy == NULL)
426 PyErr_WriteUnraisable(lst);
427 else {
428 if (reverse)
429 PyList_Reverse(cpy);
430 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
431 PyObject *func, *res;
432 func = PyList_GET_ITEM(cpy, i);
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +0200433 res = _PyObject_CallNoArg(func);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200434 if (res == NULL)
435 PyErr_WriteUnraisable(func);
436 else
437 Py_DECREF(res);
438 }
439 Py_DECREF(cpy);
440 }
441 }
442}
443
444void
445PyOS_BeforeFork(void)
446{
Victor Stinner81a7be32020-04-14 15:14:01 +0200447 run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200448
449 _PyImport_AcquireLock();
450}
451
452void
453PyOS_AfterFork_Parent(void)
454{
455 if (_PyImport_ReleaseLock() <= 0)
456 Py_FatalError("failed releasing import lock after fork");
457
Victor Stinner81a7be32020-04-14 15:14:01 +0200458 run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200459}
460
461void
462PyOS_AfterFork_Child(void)
463{
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200464 _PyRuntimeState *runtime = &_PyRuntime;
465 _PyGILState_Reinit(runtime);
Victor Stinnerd5d9e812019-05-13 12:35:37 +0200466 _PyEval_ReInitThreads(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200467 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200468 _PySignal_AfterFork();
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200469 _PyRuntimeState_ReInitThreads(runtime);
Victor Stinnerb49858b2019-05-24 15:20:23 +0200470 _PyInterpreterState_DeleteExceptMain(runtime);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200471
Victor Stinner81a7be32020-04-14 15:14:01 +0200472 run_at_forkers(_PyInterpreterState_GET()->after_forkers_child, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200473}
474
475static int
476register_at_forker(PyObject **lst, PyObject *func)
477{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700478 if (func == NULL) /* nothing to register? do nothing. */
479 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200480 if (*lst == NULL) {
481 *lst = PyList_New(0);
482 if (*lst == NULL)
483 return -1;
484 }
485 return PyList_Append(*lst, func);
486}
Victor Stinner87255be2020-04-07 23:11:49 +0200487#endif /* HAVE_FORK */
488
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200489
490/* Legacy wrapper */
491void
492PyOS_AfterFork(void)
493{
494#ifdef HAVE_FORK
495 PyOS_AfterFork_Child();
496#endif
497}
498
499
Victor Stinner6036e442015-03-08 01:58:04 +0100500#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200501/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700502void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
503void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200504 ULONG, struct _Py_stat_struct *);
505#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700506
Larry Hastings9cf065c2012-06-22 16:30:09 -0700507
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200508#ifndef MS_WINDOWS
509PyObject *
510_PyLong_FromUid(uid_t uid)
511{
512 if (uid == (uid_t)-1)
513 return PyLong_FromLong(-1);
514 return PyLong_FromUnsignedLong(uid);
515}
516
517PyObject *
518_PyLong_FromGid(gid_t gid)
519{
520 if (gid == (gid_t)-1)
521 return PyLong_FromLong(-1);
522 return PyLong_FromUnsignedLong(gid);
523}
524
525int
526_Py_Uid_Converter(PyObject *obj, void *p)
527{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528 uid_t uid;
529 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200530 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200531 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700532 unsigned long uresult;
533
534 index = PyNumber_Index(obj);
535 if (index == NULL) {
536 PyErr_Format(PyExc_TypeError,
537 "uid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800538 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200539 return 0;
540 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700541
542 /*
543 * Handling uid_t is complicated for two reasons:
544 * * Although uid_t is (always?) unsigned, it still
545 * accepts -1.
546 * * We don't know its size in advance--it may be
547 * bigger than an int, or it may be smaller than
548 * a long.
549 *
550 * So a bit of defensive programming is in order.
551 * Start with interpreting the value passed
552 * in as a signed long and see if it works.
553 */
554
555 result = PyLong_AsLongAndOverflow(index, &overflow);
556
557 if (!overflow) {
558 uid = (uid_t)result;
559
560 if (result == -1) {
561 if (PyErr_Occurred())
562 goto fail;
563 /* It's a legitimate -1, we're done. */
564 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200565 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700566
567 /* Any other negative number is disallowed. */
568 if (result < 0)
569 goto underflow;
570
571 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200572 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700573 (long)uid != result)
574 goto underflow;
575 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200576 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700577
578 if (overflow < 0)
579 goto underflow;
580
581 /*
582 * Okay, the value overflowed a signed long. If it
583 * fits in an *unsigned* long, it may still be okay,
584 * as uid_t may be unsigned long on this platform.
585 */
586 uresult = PyLong_AsUnsignedLong(index);
587 if (PyErr_Occurred()) {
588 if (PyErr_ExceptionMatches(PyExc_OverflowError))
589 goto overflow;
590 goto fail;
591 }
592
593 uid = (uid_t)uresult;
594
595 /*
596 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
597 * but this value would get interpreted as (uid_t)-1 by chown
598 * and its siblings. That's not what the user meant! So we
599 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100600 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700601 */
602 if (uid == (uid_t)-1)
603 goto overflow;
604
605 /* Ensure the value wasn't truncated. */
606 if (sizeof(uid_t) < sizeof(long) &&
607 (unsigned long)uid != uresult)
608 goto overflow;
609 /* fallthrough */
610
611success:
612 Py_DECREF(index);
613 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200614 return 1;
615
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200617 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618 "uid is less than minimum");
619 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700621overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200622 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700623 "uid is greater than maximum");
624 /* fallthrough */
625
626fail:
627 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200628 return 0;
629}
630
631int
632_Py_Gid_Converter(PyObject *obj, void *p)
633{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700634 gid_t gid;
635 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200636 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200637 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700638 unsigned long uresult;
639
640 index = PyNumber_Index(obj);
641 if (index == NULL) {
642 PyErr_Format(PyExc_TypeError,
643 "gid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800644 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200645 return 0;
646 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700647
648 /*
649 * Handling gid_t is complicated for two reasons:
650 * * Although gid_t is (always?) unsigned, it still
651 * accepts -1.
652 * * We don't know its size in advance--it may be
653 * bigger than an int, or it may be smaller than
654 * a long.
655 *
656 * So a bit of defensive programming is in order.
657 * Start with interpreting the value passed
658 * in as a signed long and see if it works.
659 */
660
661 result = PyLong_AsLongAndOverflow(index, &overflow);
662
663 if (!overflow) {
664 gid = (gid_t)result;
665
666 if (result == -1) {
667 if (PyErr_Occurred())
668 goto fail;
669 /* It's a legitimate -1, we're done. */
670 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200671 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700672
673 /* Any other negative number is disallowed. */
674 if (result < 0) {
675 goto underflow;
676 }
677
678 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200679 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680 (long)gid != result)
681 goto underflow;
682 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200683 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684
685 if (overflow < 0)
686 goto underflow;
687
688 /*
689 * Okay, the value overflowed a signed long. If it
690 * fits in an *unsigned* long, it may still be okay,
691 * as gid_t may be unsigned long on this platform.
692 */
693 uresult = PyLong_AsUnsignedLong(index);
694 if (PyErr_Occurred()) {
695 if (PyErr_ExceptionMatches(PyExc_OverflowError))
696 goto overflow;
697 goto fail;
698 }
699
700 gid = (gid_t)uresult;
701
702 /*
703 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
704 * but this value would get interpreted as (gid_t)-1 by chown
705 * and its siblings. That's not what the user meant! So we
706 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100707 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700708 */
709 if (gid == (gid_t)-1)
710 goto overflow;
711
712 /* Ensure the value wasn't truncated. */
713 if (sizeof(gid_t) < sizeof(long) &&
714 (unsigned long)gid != uresult)
715 goto overflow;
716 /* fallthrough */
717
718success:
719 Py_DECREF(index);
720 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200721 return 1;
722
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700723underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200724 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700725 "gid is less than minimum");
726 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200727
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700728overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200729 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700730 "gid is greater than maximum");
731 /* fallthrough */
732
733fail:
734 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200735 return 0;
736}
737#endif /* MS_WINDOWS */
738
739
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700740#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800741
742
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200743#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
744static int
745_Py_Dev_Converter(PyObject *obj, void *p)
746{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200747 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200748 if (PyErr_Occurred())
749 return 0;
750 return 1;
751}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800752#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200753
754
Larry Hastings9cf065c2012-06-22 16:30:09 -0700755#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400756/*
757 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
758 * without the int cast, the value gets interpreted as uint (4291925331),
759 * which doesn't play nicely with all the initializer lines in this file that
760 * look like this:
761 * int dir_fd = DEFAULT_DIR_FD;
762 */
763#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700764#else
765#define DEFAULT_DIR_FD (-100)
766#endif
767
768static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300769_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200770{
771 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700772 long long_value;
773
774 PyObject *index = PyNumber_Index(o);
775 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700776 return 0;
777 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700778
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300779 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700780 long_value = PyLong_AsLongAndOverflow(index, &overflow);
781 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300782 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200783 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700785 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700786 return 0;
787 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200788 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700789 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700790 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700791 return 0;
792 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700793
Larry Hastings9cf065c2012-06-22 16:30:09 -0700794 *p = (int)long_value;
795 return 1;
796}
797
798static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200799dir_fd_converter(PyObject *o, void *p)
800{
801 if (o == Py_None) {
802 *(int *)p = DEFAULT_DIR_FD;
803 return 1;
804 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300805 else if (PyIndex_Check(o)) {
806 return _fd_converter(o, (int *)p);
807 }
808 else {
809 PyErr_Format(PyExc_TypeError,
810 "argument should be integer or None, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800811 _PyType_Name(Py_TYPE(o)));
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300812 return 0;
813 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700814}
815
Eddie Elizondob3966632019-11-05 07:16:14 -0800816typedef struct {
817 PyObject *billion;
Eddie Elizondob3966632019-11-05 07:16:14 -0800818 PyObject *DirEntryType;
819 PyObject *ScandirIteratorType;
820#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
821 PyObject *SchedParamType;
822#endif
823 PyObject *StatResultType;
824 PyObject *StatVFSResultType;
825 PyObject *TerminalSizeType;
826 PyObject *TimesResultType;
827 PyObject *UnameResultType;
828#if defined(HAVE_WAITID) && !defined(__APPLE__)
829 PyObject *WaitidResultType;
830#endif
831#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
832 PyObject *struct_rusage;
833#endif
834 PyObject *st_mode;
835} _posixstate;
836
Eddie Elizondob3966632019-11-05 07:16:14 -0800837
Hai Shif707d942020-03-16 21:15:01 +0800838static inline _posixstate*
839get_posix_state(PyObject *module)
840{
841 void *state = PyModule_GetState(module);
842 assert(state != NULL);
843 return (_posixstate *)state;
844}
845
Larry Hastings9cf065c2012-06-22 16:30:09 -0700846/*
847 * A PyArg_ParseTuple "converter" function
848 * that handles filesystem paths in the manner
849 * preferred by the os module.
850 *
851 * path_converter accepts (Unicode) strings and their
852 * subclasses, and bytes and their subclasses. What
853 * it does with the argument depends on the platform:
854 *
855 * * On Windows, if we get a (Unicode) string we
856 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700857 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700858 *
859 * * On all other platforms, strings are encoded
860 * to bytes using PyUnicode_FSConverter, then we
861 * extract the char * from the bytes object and
862 * return that.
863 *
864 * path_converter also optionally accepts signed
865 * integers (representing open file descriptors) instead
866 * of path strings.
867 *
868 * Input fields:
869 * path.nullable
870 * If nonzero, the path is permitted to be None.
871 * path.allow_fd
872 * If nonzero, the path is permitted to be a file handle
873 * (a signed int) instead of a string.
874 * path.function_name
875 * If non-NULL, path_converter will use that as the name
876 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700877 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700878 * path.argument_name
879 * If non-NULL, path_converter will use that as the name
880 * of the parameter in error messages.
881 * (If path.argument_name is NULL it uses "path".)
882 *
883 * Output fields:
884 * path.wide
885 * Points to the path if it was expressed as Unicode
886 * and was not encoded. (Only used on Windows.)
887 * path.narrow
888 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700889 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000890 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700891 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700892 * path.fd
893 * Contains a file descriptor if path.accept_fd was true
894 * and the caller provided a signed integer instead of any
895 * sort of string.
896 *
897 * WARNING: if your "path" parameter is optional, and is
898 * unspecified, path_converter will never get called.
899 * So if you set allow_fd, you *MUST* initialize path.fd = -1
900 * yourself!
901 * path.length
902 * The length of the path in characters, if specified as
903 * a string.
904 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800905 * The original object passed in (if get a PathLike object,
906 * the result of PyOS_FSPath() is treated as the original object).
907 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700908 * path.cleanup
909 * For internal use only. May point to a temporary object.
910 * (Pay no attention to the man behind the curtain.)
911 *
912 * At most one of path.wide or path.narrow will be non-NULL.
913 * If path was None and path.nullable was set,
914 * or if path was an integer and path.allow_fd was set,
915 * both path.wide and path.narrow will be NULL
916 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200917 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700918 * path_converter takes care to not write to the path_t
919 * unless it's successful. However it must reset the
920 * "cleanup" field each time it's called.
921 *
922 * Use as follows:
923 * path_t path;
924 * memset(&path, 0, sizeof(path));
925 * PyArg_ParseTuple(args, "O&", path_converter, &path);
926 * // ... use values from path ...
927 * path_cleanup(&path);
928 *
929 * (Note that if PyArg_Parse fails you don't need to call
930 * path_cleanup(). However it is safe to do so.)
931 */
932typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100933 const char *function_name;
934 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935 int nullable;
936 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300937 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700938#ifdef MS_WINDOWS
939 BOOL narrow;
940#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300941 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700942#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943 int fd;
944 Py_ssize_t length;
945 PyObject *object;
946 PyObject *cleanup;
947} path_t;
948
Steve Dowercc16be82016-09-08 10:35:16 -0700949#ifdef MS_WINDOWS
950#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
951 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
952#else
Larry Hastings2f936352014-08-05 14:04:04 +1000953#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
954 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700955#endif
Larry Hastings31826802013-10-19 00:09:25 -0700956
Larry Hastings9cf065c2012-06-22 16:30:09 -0700957static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800958path_cleanup(path_t *path)
959{
960 Py_CLEAR(path->object);
961 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700962}
963
964static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300965path_converter(PyObject *o, void *p)
966{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800968 PyObject *bytes = NULL;
969 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700970 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300971 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700972#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800973 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700974 const wchar_t *wide;
975#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700976
977#define FORMAT_EXCEPTION(exc, fmt) \
978 PyErr_Format(exc, "%s%s" fmt, \
979 path->function_name ? path->function_name : "", \
980 path->function_name ? ": " : "", \
981 path->argument_name ? path->argument_name : "path")
982
983 /* Py_CLEANUP_SUPPORTED support */
984 if (o == NULL) {
985 path_cleanup(path);
986 return 1;
987 }
988
Brett Cannon3f9183b2016-08-26 14:44:48 -0700989 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800990 path->object = path->cleanup = NULL;
991 /* path->object owns a reference to the original object */
992 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700993
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300994 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700995 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700996#ifdef MS_WINDOWS
997 path->narrow = FALSE;
998#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700999 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001000#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001002 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001003 }
1004
Brett Cannon3f9183b2016-08-26 14:44:48 -07001005 /* Only call this here so that we don't treat the return value of
1006 os.fspath() as an fd or buffer. */
1007 is_index = path->allow_fd && PyIndex_Check(o);
1008 is_buffer = PyObject_CheckBuffer(o);
1009 is_bytes = PyBytes_Check(o);
1010 is_unicode = PyUnicode_Check(o);
1011
1012 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
1013 /* Inline PyOS_FSPath() for better error messages. */
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001014 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001015
1016 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1017 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001018 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001019 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001020 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001021 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001022 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001023 goto error_exit;
1024 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001025 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001026 is_unicode = 1;
1027 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001028 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001029 is_bytes = 1;
1030 }
1031 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001032 PyErr_Format(PyExc_TypeError,
1033 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -08001034 "not %.200s", _PyType_Name(Py_TYPE(o)),
1035 _PyType_Name(Py_TYPE(res)));
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001036 Py_DECREF(res);
1037 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001038 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001039
1040 /* still owns a reference to the original object */
1041 Py_DECREF(o);
1042 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001043 }
1044
1045 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001046#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001047 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001048 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001049 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001050 }
Victor Stinner59799a82013-11-13 14:17:30 +01001051 if (length > 32767) {
1052 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001053 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001054 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001055 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001056 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001057 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001058 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001059
1060 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001061 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001062 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001063 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001064#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001065 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001066 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001067 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001068#endif
1069 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001070 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001071 bytes = o;
1072 Py_INCREF(bytes);
1073 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001074 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001075 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001076 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001077 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1078 "%s%s%s should be %s, not %.200s",
1079 path->function_name ? path->function_name : "",
1080 path->function_name ? ": " : "",
1081 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001082 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1083 "integer or None" :
1084 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1085 path->nullable ? "string, bytes, os.PathLike or None" :
1086 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001087 _PyType_Name(Py_TYPE(o)))) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001088 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001089 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001090 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001091 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001092 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001093 }
1094 }
Steve Dowercc16be82016-09-08 10:35:16 -07001095 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001096 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001097 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001098 }
1099 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001100#ifdef MS_WINDOWS
1101 path->narrow = FALSE;
1102#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001103 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001104#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001105 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001106 }
1107 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001108 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001109 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1110 path->function_name ? path->function_name : "",
1111 path->function_name ? ": " : "",
1112 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001113 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1114 "integer or None" :
1115 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1116 path->nullable ? "string, bytes, os.PathLike or None" :
1117 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001118 _PyType_Name(Py_TYPE(o)));
Xiang Zhang04316c42017-01-08 23:26:57 +08001119 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001120 }
1121
Larry Hastings9cf065c2012-06-22 16:30:09 -07001122 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001123 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001124 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001125 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001126 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001127 }
1128
Steve Dowercc16be82016-09-08 10:35:16 -07001129#ifdef MS_WINDOWS
1130 wo = PyUnicode_DecodeFSDefaultAndSize(
1131 narrow,
1132 length
1133 );
1134 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001135 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001136 }
1137
Xiang Zhang04316c42017-01-08 23:26:57 +08001138 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001139 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001140 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001141 }
1142 if (length > 32767) {
1143 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001144 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001145 }
1146 if (wcslen(wide) != length) {
1147 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001148 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001149 }
1150 path->wide = wide;
1151 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001152 path->cleanup = wo;
1153 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001154#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001155 path->wide = NULL;
1156 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001157 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001158 /* Still a reference owned by path->object, don't have to
1159 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001160 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001161 }
1162 else {
1163 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001164 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001165#endif
1166 path->fd = -1;
1167
1168 success_exit:
1169 path->length = length;
1170 path->object = o;
1171 return Py_CLEANUP_SUPPORTED;
1172
1173 error_exit:
1174 Py_XDECREF(o);
1175 Py_XDECREF(bytes);
1176#ifdef MS_WINDOWS
1177 Py_XDECREF(wo);
1178#endif
1179 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001180}
1181
1182static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001183argument_unavailable_error(const char *function_name, const char *argument_name)
1184{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001185 PyErr_Format(PyExc_NotImplementedError,
1186 "%s%s%s unavailable on this platform",
1187 (function_name != NULL) ? function_name : "",
1188 (function_name != NULL) ? ": ": "",
1189 argument_name);
1190}
1191
1192static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001193dir_fd_unavailable(PyObject *o, void *p)
1194{
1195 int dir_fd;
1196 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001197 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001198 if (dir_fd != DEFAULT_DIR_FD) {
1199 argument_unavailable_error(NULL, "dir_fd");
1200 return 0;
1201 }
1202 *(int *)p = dir_fd;
1203 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001204}
1205
1206static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001207fd_specified(const char *function_name, int fd)
1208{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001209 if (fd == -1)
1210 return 0;
1211
1212 argument_unavailable_error(function_name, "fd");
1213 return 1;
1214}
1215
1216static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001217follow_symlinks_specified(const char *function_name, int follow_symlinks)
1218{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 if (follow_symlinks)
1220 return 0;
1221
1222 argument_unavailable_error(function_name, "follow_symlinks");
1223 return 1;
1224}
1225
1226static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001227path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1228{
Steve Dowercc16be82016-09-08 10:35:16 -07001229 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1230#ifndef MS_WINDOWS
1231 && !path->narrow
1232#endif
1233 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001234 PyErr_Format(PyExc_ValueError,
1235 "%s: can't specify dir_fd without matching path",
1236 function_name);
1237 return 1;
1238 }
1239 return 0;
1240}
1241
1242static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001243dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1244{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001245 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1246 PyErr_Format(PyExc_ValueError,
1247 "%s: can't specify both dir_fd and fd",
1248 function_name);
1249 return 1;
1250 }
1251 return 0;
1252}
1253
1254static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001255fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1256 int follow_symlinks)
1257{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001258 if ((fd > 0) && (!follow_symlinks)) {
1259 PyErr_Format(PyExc_ValueError,
1260 "%s: cannot use fd and follow_symlinks together",
1261 function_name);
1262 return 1;
1263 }
1264 return 0;
1265}
1266
1267static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001268dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1269 int follow_symlinks)
1270{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001271 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1272 PyErr_Format(PyExc_ValueError,
1273 "%s: cannot use dir_fd and follow_symlinks together",
1274 function_name);
1275 return 1;
1276 }
1277 return 0;
1278}
1279
Larry Hastings2f936352014-08-05 14:04:04 +10001280#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001281 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001282#else
Larry Hastings2f936352014-08-05 14:04:04 +10001283 typedef off_t Py_off_t;
1284#endif
1285
1286static int
1287Py_off_t_converter(PyObject *arg, void *addr)
1288{
1289#ifdef HAVE_LARGEFILE_SUPPORT
1290 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1291#else
1292 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001293#endif
1294 if (PyErr_Occurred())
1295 return 0;
1296 return 1;
1297}
Larry Hastings2f936352014-08-05 14:04:04 +10001298
1299static PyObject *
1300PyLong_FromPy_off_t(Py_off_t offset)
1301{
1302#ifdef HAVE_LARGEFILE_SUPPORT
1303 return PyLong_FromLongLong(offset);
1304#else
1305 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001306#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001307}
1308
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001309#ifdef HAVE_SIGSET_T
1310/* Convert an iterable of integers to a sigset.
1311 Return 1 on success, return 0 and raise an exception on error. */
1312int
1313_Py_Sigset_Converter(PyObject *obj, void *addr)
1314{
1315 sigset_t *mask = (sigset_t *)addr;
1316 PyObject *iterator, *item;
1317 long signum;
1318 int overflow;
1319
Rémi Lapeyref0900192019-05-04 01:30:53 +02001320 // The extra parens suppress the unreachable-code warning with clang on MacOS
1321 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001322 /* Probably only if mask == NULL. */
1323 PyErr_SetFromErrno(PyExc_OSError);
1324 return 0;
1325 }
1326
1327 iterator = PyObject_GetIter(obj);
1328 if (iterator == NULL) {
1329 return 0;
1330 }
1331
1332 while ((item = PyIter_Next(iterator)) != NULL) {
1333 signum = PyLong_AsLongAndOverflow(item, &overflow);
1334 Py_DECREF(item);
1335 if (signum <= 0 || signum >= NSIG) {
1336 if (overflow || signum != -1 || !PyErr_Occurred()) {
1337 PyErr_Format(PyExc_ValueError,
1338 "signal number %ld out of range", signum);
1339 }
1340 goto error;
1341 }
1342 if (sigaddset(mask, (int)signum)) {
1343 if (errno != EINVAL) {
1344 /* Probably impossible */
1345 PyErr_SetFromErrno(PyExc_OSError);
1346 goto error;
1347 }
1348 /* For backwards compatibility, allow idioms such as
1349 * `range(1, NSIG)` but warn about invalid signal numbers
1350 */
1351 const char msg[] =
1352 "invalid signal number %ld, please use valid_signals()";
1353 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1354 goto error;
1355 }
1356 }
1357 }
1358 if (!PyErr_Occurred()) {
1359 Py_DECREF(iterator);
1360 return 1;
1361 }
1362
1363error:
1364 Py_DECREF(iterator);
1365 return 0;
1366}
1367#endif /* HAVE_SIGSET_T */
1368
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001369#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001370
1371static int
Brian Curtind25aef52011-06-13 15:16:04 -05001372win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001373{
Martin Panter70214ad2016-08-04 02:38:59 +00001374 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1375 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001376 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001377
1378 if (0 == DeviceIoControl(
1379 reparse_point_handle,
1380 FSCTL_GET_REPARSE_POINT,
1381 NULL, 0, /* in buffer */
1382 target_buffer, sizeof(target_buffer),
1383 &n_bytes_returned,
1384 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001385 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001386
1387 if (reparse_tag)
1388 *reparse_tag = rdb->ReparseTag;
1389
Brian Curtind25aef52011-06-13 15:16:04 -05001390 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001391}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001392
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001393#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001394
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001395/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001396#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001397/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001398** environ directly, we must obtain it with _NSGetEnviron(). See also
1399** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001400*/
1401#include <crt_externs.h>
pxinwrf2d7ac72019-05-21 18:46:37 +08001402#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001403extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001404#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001405
Barry Warsaw53699e91996-12-10 23:23:01 +00001406static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001407convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001408{
Victor Stinner8c62be82010-05-06 00:08:46 +00001409 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001410#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001411 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001412#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001414#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001415
Victor Stinner8c62be82010-05-06 00:08:46 +00001416 d = PyDict_New();
1417 if (d == NULL)
1418 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001419#ifdef MS_WINDOWS
1420 /* _wenviron must be initialized in this way if the program is started
1421 through main() instead of wmain(). */
1422 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001423 e = _wenviron;
Benoit Hudson723f71a2019-12-06 14:15:03 -05001424#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1425 /* environ is not accessible as an extern in a shared object on OSX; use
1426 _NSGetEnviron to resolve it. The value changes if you add environment
1427 variables between calls to Py_Initialize, so don't cache the value. */
1428 e = *_NSGetEnviron();
Victor Stinner8c62be82010-05-06 00:08:46 +00001429#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001430 e = environ;
1431#endif
1432 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001433 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001434 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001435 PyObject *k;
1436 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001437#ifdef MS_WINDOWS
1438 const wchar_t *p = wcschr(*e, L'=');
1439#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001440 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001441#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001442 if (p == NULL)
1443 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001444#ifdef MS_WINDOWS
1445 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1446#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001447 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001448#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001449 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001450 Py_DECREF(d);
1451 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001452 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001453#ifdef MS_WINDOWS
1454 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1455#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001456 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001457#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001458 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001459 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001460 Py_DECREF(d);
1461 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001462 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001463 if (PyDict_GetItemWithError(d, k) == NULL) {
1464 if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) {
1465 Py_DECREF(v);
1466 Py_DECREF(k);
1467 Py_DECREF(d);
1468 return NULL;
1469 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001470 }
1471 Py_DECREF(k);
1472 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001473 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001474 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001475}
1476
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001477/* Set a POSIX-specific error from errno, and return NULL */
1478
Barry Warsawd58d7641998-07-23 16:14:40 +00001479static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001480posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001481{
Victor Stinner8c62be82010-05-06 00:08:46 +00001482 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001483}
Mark Hammondef8b6542001-05-13 08:04:26 +00001484
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001485#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001486static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001487win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001488{
Victor Stinner8c62be82010-05-06 00:08:46 +00001489 /* XXX We should pass the function name along in the future.
1490 (winreg.c also wants to pass the function name.)
1491 This would however require an additional param to the
1492 Windows error object, which is non-trivial.
1493 */
1494 errno = GetLastError();
1495 if (filename)
1496 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1497 else
1498 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001499}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001500
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001501static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001502win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001503{
1504 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001505 if (filename)
1506 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001507 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001508 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001509 filename);
1510 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001511 return PyErr_SetFromWindowsErr(err);
1512}
1513
1514static PyObject *
1515win32_error_object(const char* function, PyObject* filename)
1516{
1517 errno = GetLastError();
1518 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001519}
1520
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001521#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001522
Larry Hastings9cf065c2012-06-22 16:30:09 -07001523static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001524posix_path_object_error(PyObject *path)
1525{
1526 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1527}
1528
1529static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001530path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001531{
1532#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001533 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1534 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001535#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001536 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001537#endif
1538}
1539
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001540static PyObject *
1541path_object_error2(PyObject *path, PyObject *path2)
1542{
1543#ifdef MS_WINDOWS
1544 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1545 PyExc_OSError, 0, path, path2);
1546#else
1547 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1548#endif
1549}
1550
1551static PyObject *
1552path_error(path_t *path)
1553{
1554 return path_object_error(path->object);
1555}
Larry Hastings31826802013-10-19 00:09:25 -07001556
Larry Hastingsb0827312014-02-09 22:05:19 -08001557static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001558posix_path_error(path_t *path)
1559{
1560 return posix_path_object_error(path->object);
1561}
1562
1563static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001564path_error2(path_t *path, path_t *path2)
1565{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001566 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001567}
1568
1569
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001570/* POSIX generic methods */
1571
Larry Hastings2f936352014-08-05 14:04:04 +10001572static int
1573fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001574{
Victor Stinner8c62be82010-05-06 00:08:46 +00001575 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001576 int *pointer = (int *)p;
1577 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001578 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001579 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001580 *pointer = fd;
1581 return 1;
1582}
1583
1584static PyObject *
1585posix_fildes_fd(int fd, int (*func)(int))
1586{
1587 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001588 int async_err = 0;
1589
1590 do {
1591 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001592 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001593 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001594 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001595 Py_END_ALLOW_THREADS
1596 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1597 if (res != 0)
1598 return (!async_err) ? posix_error() : NULL;
1599 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001600}
Guido van Rossum21142a01999-01-08 21:05:37 +00001601
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001602
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001603#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001604/* This is a reimplementation of the C library's chdir function,
1605 but one that produces Win32 errors instead of DOS error codes.
1606 chdir is essentially a wrapper around SetCurrentDirectory; however,
1607 it also needs to set "magic" environment variables indicating
1608 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001609static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001610win32_wchdir(LPCWSTR path)
1611{
Victor Stinnered537822015-12-13 21:40:26 +01001612 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001613 int result;
1614 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001615
Victor Stinner8c62be82010-05-06 00:08:46 +00001616 if(!SetCurrentDirectoryW(path))
1617 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001618 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001619 if (!result)
1620 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001621 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001622 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001623 if (!new_path) {
1624 SetLastError(ERROR_OUTOFMEMORY);
1625 return FALSE;
1626 }
1627 result = GetCurrentDirectoryW(result, new_path);
1628 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001629 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001630 return FALSE;
1631 }
1632 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001633 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1634 wcsncmp(new_path, L"//", 2) == 0);
1635 if (!is_unc_like_path) {
1636 env[1] = new_path[0];
1637 result = SetEnvironmentVariableW(env, new_path);
1638 }
Victor Stinnered537822015-12-13 21:40:26 +01001639 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001640 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001641 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001642}
1643#endif
1644
Martin v. Löwis14694662006-02-03 12:54:16 +00001645#ifdef MS_WINDOWS
1646/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1647 - time stamps are restricted to second resolution
1648 - file modification times suffer from forth-and-back conversions between
1649 UTC and local time
1650 Therefore, we implement our own stat, based on the Win32 API directly.
1651*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001652#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001653#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001654#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001655
Victor Stinner6036e442015-03-08 01:58:04 +01001656static void
Steve Dowercc16be82016-09-08 10:35:16 -07001657find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1658 BY_HANDLE_FILE_INFORMATION *info,
1659 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001660{
1661 memset(info, 0, sizeof(*info));
1662 info->dwFileAttributes = pFileData->dwFileAttributes;
1663 info->ftCreationTime = pFileData->ftCreationTime;
1664 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1665 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1666 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1667 info->nFileSizeLow = pFileData->nFileSizeLow;
1668/* info->nNumberOfLinks = 1; */
1669 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1670 *reparse_tag = pFileData->dwReserved0;
1671 else
1672 *reparse_tag = 0;
1673}
1674
Guido van Rossumd8faa362007-04-27 19:54:29 +00001675static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001676attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001677{
Victor Stinner8c62be82010-05-06 00:08:46 +00001678 HANDLE hFindFile;
1679 WIN32_FIND_DATAW FileData;
1680 hFindFile = FindFirstFileW(pszFile, &FileData);
1681 if (hFindFile == INVALID_HANDLE_VALUE)
1682 return FALSE;
1683 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001684 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001685 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001686}
1687
Brian Curtind25aef52011-06-13 15:16:04 -05001688static int
Steve Dowercc16be82016-09-08 10:35:16 -07001689win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001690 BOOL traverse)
1691{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001692 HANDLE hFile;
1693 BY_HANDLE_FILE_INFORMATION fileInfo;
1694 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1695 DWORD fileType, error;
1696 BOOL isUnhandledTag = FALSE;
1697 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001698
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001699 DWORD access = FILE_READ_ATTRIBUTES;
1700 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1701 if (!traverse) {
1702 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1703 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001704
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001705 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001706 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001707 /* Either the path doesn't exist, or the caller lacks access. */
1708 error = GetLastError();
1709 switch (error) {
1710 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1711 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1712 /* Try reading the parent directory. */
1713 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1714 /* Cannot read the parent directory. */
1715 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001716 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001717 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001718 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1719 if (traverse ||
1720 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1721 /* The stat call has to traverse but cannot, so fail. */
1722 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001723 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001724 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001725 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001726 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001727
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001728 case ERROR_INVALID_PARAMETER:
1729 /* \\.\con requires read or write access. */
1730 hFile = CreateFileW(path, access | GENERIC_READ,
1731 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1732 OPEN_EXISTING, flags, NULL);
1733 if (hFile == INVALID_HANDLE_VALUE) {
1734 SetLastError(error);
1735 return -1;
1736 }
1737 break;
1738
1739 case ERROR_CANT_ACCESS_FILE:
1740 /* bpo37834: open unhandled reparse points if traverse fails. */
1741 if (traverse) {
1742 traverse = FALSE;
1743 isUnhandledTag = TRUE;
1744 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1745 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1746 }
1747 if (hFile == INVALID_HANDLE_VALUE) {
1748 SetLastError(error);
1749 return -1;
1750 }
1751 break;
1752
1753 default:
1754 return -1;
1755 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001756 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001757
1758 if (hFile != INVALID_HANDLE_VALUE) {
1759 /* Handle types other than files on disk. */
1760 fileType = GetFileType(hFile);
1761 if (fileType != FILE_TYPE_DISK) {
1762 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1763 retval = -1;
1764 goto cleanup;
1765 }
1766 DWORD fileAttributes = GetFileAttributesW(path);
1767 memset(result, 0, sizeof(*result));
1768 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1769 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1770 /* \\.\pipe\ or \\.\mailslot\ */
1771 result->st_mode = _S_IFDIR;
1772 } else if (fileType == FILE_TYPE_CHAR) {
1773 /* \\.\nul */
1774 result->st_mode = _S_IFCHR;
1775 } else if (fileType == FILE_TYPE_PIPE) {
1776 /* \\.\pipe\spam */
1777 result->st_mode = _S_IFIFO;
1778 }
1779 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1780 goto cleanup;
1781 }
1782
1783 /* Query the reparse tag, and traverse a non-link. */
1784 if (!traverse) {
1785 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1786 &tagInfo, sizeof(tagInfo))) {
1787 /* Allow devices that do not support FileAttributeTagInfo. */
1788 switch (GetLastError()) {
1789 case ERROR_INVALID_PARAMETER:
1790 case ERROR_INVALID_FUNCTION:
1791 case ERROR_NOT_SUPPORTED:
1792 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1793 tagInfo.ReparseTag = 0;
1794 break;
1795 default:
1796 retval = -1;
1797 goto cleanup;
1798 }
1799 } else if (tagInfo.FileAttributes &
1800 FILE_ATTRIBUTE_REPARSE_POINT) {
1801 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1802 if (isUnhandledTag) {
1803 /* Traversing previously failed for either this link
1804 or its target. */
1805 SetLastError(ERROR_CANT_ACCESS_FILE);
1806 retval = -1;
1807 goto cleanup;
1808 }
1809 /* Traverse a non-link, but not if traversing already failed
1810 for an unhandled tag. */
1811 } else if (!isUnhandledTag) {
1812 CloseHandle(hFile);
1813 return win32_xstat_impl(path, result, TRUE);
1814 }
1815 }
1816 }
1817
1818 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1819 switch (GetLastError()) {
1820 case ERROR_INVALID_PARAMETER:
1821 case ERROR_INVALID_FUNCTION:
1822 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07001823 /* Volumes and physical disks are block devices, e.g.
1824 \\.\C: and \\.\PhysicalDrive0. */
1825 memset(result, 0, sizeof(*result));
1826 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001827 goto cleanup;
1828 }
Steve Dower772ec0f2019-09-04 14:42:54 -07001829 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001830 goto cleanup;
1831 }
1832 }
1833
1834 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
1835
1836 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
1837 /* Fix the file execute permissions. This hack sets S_IEXEC if
1838 the filename has an extension that is commonly used by files
1839 that CreateProcessW can execute. A real implementation calls
1840 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
1841 AccessCheck to check for generic read, write, and execute
1842 access. */
1843 const wchar_t *fileExtension = wcsrchr(path, '.');
1844 if (fileExtension) {
1845 if (_wcsicmp(fileExtension, L".exe") == 0 ||
1846 _wcsicmp(fileExtension, L".bat") == 0 ||
1847 _wcsicmp(fileExtension, L".cmd") == 0 ||
1848 _wcsicmp(fileExtension, L".com") == 0) {
1849 result->st_mode |= 0111;
1850 }
1851 }
1852 }
1853
1854cleanup:
1855 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07001856 /* Preserve last error if we are failing */
1857 error = retval ? GetLastError() : 0;
1858 if (!CloseHandle(hFile)) {
1859 retval = -1;
1860 } else if (retval) {
1861 /* Restore last error */
1862 SetLastError(error);
1863 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001864 }
1865
1866 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001867}
1868
1869static int
Steve Dowercc16be82016-09-08 10:35:16 -07001870win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001871{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001872 /* Protocol violation: we explicitly clear errno, instead of
1873 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001874 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001875 errno = 0;
1876 return code;
1877}
Brian Curtind25aef52011-06-13 15:16:04 -05001878/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001879
1880 In Posix, stat automatically traverses symlinks and returns the stat
1881 structure for the target. In Windows, the equivalent GetFileAttributes by
1882 default does not traverse symlinks and instead returns attributes for
1883 the symlink.
1884
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001885 Instead, we will open the file (which *does* traverse symlinks by default)
1886 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00001887
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001888static int
Steve Dowercc16be82016-09-08 10:35:16 -07001889win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001890{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001891 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001892}
1893
Victor Stinner8c62be82010-05-06 00:08:46 +00001894static int
Steve Dowercc16be82016-09-08 10:35:16 -07001895win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001896{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001897 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001898}
1899
Martin v. Löwis14694662006-02-03 12:54:16 +00001900#endif /* MS_WINDOWS */
1901
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001902PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001903"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001904This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001905 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001906or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1907\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001908Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1909or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001910\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001911See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001912
1913static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 {"st_mode", "protection bits"},
1915 {"st_ino", "inode"},
1916 {"st_dev", "device"},
1917 {"st_nlink", "number of hard links"},
1918 {"st_uid", "user ID of owner"},
1919 {"st_gid", "group ID of owner"},
1920 {"st_size", "total size, in bytes"},
1921 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1922 {NULL, "integer time of last access"},
1923 {NULL, "integer time of last modification"},
1924 {NULL, "integer time of last change"},
1925 {"st_atime", "time of last access"},
1926 {"st_mtime", "time of last modification"},
1927 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001928 {"st_atime_ns", "time of last access in nanoseconds"},
1929 {"st_mtime_ns", "time of last modification in nanoseconds"},
1930 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001931#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001932 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001933#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001934#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001935 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001936#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001937#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001939#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001940#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001941 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001942#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001943#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001944 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001945#endif
1946#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001947 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001948#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001949#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1950 {"st_file_attributes", "Windows file attribute bits"},
1951#endif
jcea6c51d512018-01-28 14:00:08 +01001952#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1953 {"st_fstype", "Type of filesystem"},
1954#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001955#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
1956 {"st_reparse_tag", "Windows reparse tag"},
1957#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001959};
1960
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001961#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001962#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001963#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001964#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001965#endif
1966
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001967#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001968#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1969#else
1970#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1971#endif
1972
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001973#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001974#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1975#else
1976#define ST_RDEV_IDX ST_BLOCKS_IDX
1977#endif
1978
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001979#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1980#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1981#else
1982#define ST_FLAGS_IDX ST_RDEV_IDX
1983#endif
1984
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001985#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001986#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001987#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001988#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001989#endif
1990
1991#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1992#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1993#else
1994#define ST_BIRTHTIME_IDX ST_GEN_IDX
1995#endif
1996
Zachary Ware63f277b2014-06-19 09:46:37 -05001997#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1998#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1999#else
2000#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2001#endif
2002
jcea6c51d512018-01-28 14:00:08 +01002003#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2004#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2005#else
2006#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2007#endif
2008
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002009#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2010#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2011#else
2012#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2013#endif
2014
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002015static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002016 "stat_result", /* name */
2017 stat_result__doc__, /* doc */
2018 stat_result_fields,
2019 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002020};
2021
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002022PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002023"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2024This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002025 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002026or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002027\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002028See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002029
2030static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 {"f_bsize", },
2032 {"f_frsize", },
2033 {"f_blocks", },
2034 {"f_bfree", },
2035 {"f_bavail", },
2036 {"f_files", },
2037 {"f_ffree", },
2038 {"f_favail", },
2039 {"f_flag", },
2040 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002041 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002042 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002043};
2044
2045static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002046 "statvfs_result", /* name */
2047 statvfs_result__doc__, /* doc */
2048 statvfs_result_fields,
2049 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002050};
2051
Ross Lagerwall7807c352011-03-17 20:20:30 +02002052#if defined(HAVE_WAITID) && !defined(__APPLE__)
2053PyDoc_STRVAR(waitid_result__doc__,
2054"waitid_result: Result from waitid.\n\n\
2055This object may be accessed either as a tuple of\n\
2056 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2057or via the attributes si_pid, si_uid, and so on.\n\
2058\n\
2059See os.waitid for more information.");
2060
2061static PyStructSequence_Field waitid_result_fields[] = {
2062 {"si_pid", },
2063 {"si_uid", },
2064 {"si_signo", },
2065 {"si_status", },
2066 {"si_code", },
2067 {0}
2068};
2069
2070static PyStructSequence_Desc waitid_result_desc = {
2071 "waitid_result", /* name */
2072 waitid_result__doc__, /* doc */
2073 waitid_result_fields,
2074 5
2075};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002076#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002077static newfunc structseq_new;
2078
2079static PyObject *
2080statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2081{
Victor Stinner8c62be82010-05-06 00:08:46 +00002082 PyStructSequence *result;
2083 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002084
Victor Stinner8c62be82010-05-06 00:08:46 +00002085 result = (PyStructSequence*)structseq_new(type, args, kwds);
2086 if (!result)
2087 return NULL;
2088 /* If we have been initialized from a tuple,
2089 st_?time might be set to None. Initialize it
2090 from the int slots. */
2091 for (i = 7; i <= 9; i++) {
2092 if (result->ob_item[i+3] == Py_None) {
2093 Py_DECREF(Py_None);
2094 Py_INCREF(result->ob_item[i]);
2095 result->ob_item[i+3] = result->ob_item[i];
2096 }
2097 }
2098 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002099}
2100
Eddie Elizondob3966632019-11-05 07:16:14 -08002101static int
2102_posix_clear(PyObject *module)
2103{
Hai Shif707d942020-03-16 21:15:01 +08002104 Py_CLEAR(get_posix_state(module)->billion);
2105 Py_CLEAR(get_posix_state(module)->DirEntryType);
2106 Py_CLEAR(get_posix_state(module)->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002107#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Hai Shif707d942020-03-16 21:15:01 +08002108 Py_CLEAR(get_posix_state(module)->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002109#endif
Hai Shif707d942020-03-16 21:15:01 +08002110 Py_CLEAR(get_posix_state(module)->StatResultType);
2111 Py_CLEAR(get_posix_state(module)->StatVFSResultType);
2112 Py_CLEAR(get_posix_state(module)->TerminalSizeType);
2113 Py_CLEAR(get_posix_state(module)->TimesResultType);
2114 Py_CLEAR(get_posix_state(module)->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002115#if defined(HAVE_WAITID) && !defined(__APPLE__)
Hai Shif707d942020-03-16 21:15:01 +08002116 Py_CLEAR(get_posix_state(module)->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002117#endif
2118#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Hai Shif707d942020-03-16 21:15:01 +08002119 Py_CLEAR(get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002120#endif
Hai Shif707d942020-03-16 21:15:01 +08002121 Py_CLEAR(get_posix_state(module)->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002122 return 0;
2123}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002124
Eddie Elizondob3966632019-11-05 07:16:14 -08002125static int
2126_posix_traverse(PyObject *module, visitproc visit, void *arg)
2127{
Hai Shif707d942020-03-16 21:15:01 +08002128 Py_VISIT(get_posix_state(module)->billion);
2129 Py_VISIT(get_posix_state(module)->DirEntryType);
2130 Py_VISIT(get_posix_state(module)->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002131#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Hai Shif707d942020-03-16 21:15:01 +08002132 Py_VISIT(get_posix_state(module)->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002133#endif
Hai Shif707d942020-03-16 21:15:01 +08002134 Py_VISIT(get_posix_state(module)->StatResultType);
2135 Py_VISIT(get_posix_state(module)->StatVFSResultType);
2136 Py_VISIT(get_posix_state(module)->TerminalSizeType);
2137 Py_VISIT(get_posix_state(module)->TimesResultType);
2138 Py_VISIT(get_posix_state(module)->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002139#if defined(HAVE_WAITID) && !defined(__APPLE__)
Hai Shif707d942020-03-16 21:15:01 +08002140 Py_VISIT(get_posix_state(module)->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002141#endif
2142#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Hai Shif707d942020-03-16 21:15:01 +08002143 Py_VISIT(get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002144#endif
Hai Shif707d942020-03-16 21:15:01 +08002145 Py_VISIT(get_posix_state(module)->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002146 return 0;
2147}
2148
2149static void
2150_posix_free(void *module)
2151{
2152 _posix_clear((PyObject *)module);
2153}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002154
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002155static void
Victor Stinner1c2fa782020-05-10 11:05:29 +02002156fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002157{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002158 PyObject *s = _PyLong_FromTime_t(sec);
2159 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2160 PyObject *s_in_ns = NULL;
2161 PyObject *ns_total = NULL;
2162 PyObject *float_s = NULL;
2163
2164 if (!(s && ns_fractional))
2165 goto exit;
2166
Victor Stinner1c2fa782020-05-10 11:05:29 +02002167 s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002168 if (!s_in_ns)
2169 goto exit;
2170
2171 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2172 if (!ns_total)
2173 goto exit;
2174
Victor Stinner01b5aab2017-10-24 02:02:00 -07002175 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2176 if (!float_s) {
2177 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002178 }
2179
2180 PyStructSequence_SET_ITEM(v, index, s);
2181 PyStructSequence_SET_ITEM(v, index+3, float_s);
2182 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2183 s = NULL;
2184 float_s = NULL;
2185 ns_total = NULL;
2186exit:
2187 Py_XDECREF(s);
2188 Py_XDECREF(ns_fractional);
2189 Py_XDECREF(s_in_ns);
2190 Py_XDECREF(ns_total);
2191 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002192}
2193
Tim Peters5aa91602002-01-30 05:46:57 +00002194/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002195 (used by posix_stat() and posix_fstat()) */
2196static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +02002197_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002198{
Victor Stinner8c62be82010-05-06 00:08:46 +00002199 unsigned long ansec, mnsec, cnsec;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002200 PyObject *StatResultType = get_posix_state(module)->StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08002201 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002202 if (v == NULL)
2203 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002204
Victor Stinner8c62be82010-05-06 00:08:46 +00002205 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002206 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002207 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002208#ifdef MS_WINDOWS
2209 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002210#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002211 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002212#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002213 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002214#if defined(MS_WINDOWS)
2215 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2216 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2217#else
2218 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2219 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2220#endif
xdegaye50e86032017-05-22 11:15:08 +02002221 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2222 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002223
Martin v. Löwis14694662006-02-03 12:54:16 +00002224#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002225 ansec = st->st_atim.tv_nsec;
2226 mnsec = st->st_mtim.tv_nsec;
2227 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002228#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002229 ansec = st->st_atimespec.tv_nsec;
2230 mnsec = st->st_mtimespec.tv_nsec;
2231 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002232#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002233 ansec = st->st_atime_nsec;
2234 mnsec = st->st_mtime_nsec;
2235 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002236#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002237 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002238#endif
Victor Stinner1c2fa782020-05-10 11:05:29 +02002239 fill_time(module, v, 7, st->st_atime, ansec);
2240 fill_time(module, v, 8, st->st_mtime, mnsec);
2241 fill_time(module, v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002242
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002243#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002244 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2245 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002246#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002247#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002248 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2249 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002250#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002251#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002252 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2253 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002254#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002255#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002256 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2257 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002258#endif
2259#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002260 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002261 PyObject *val;
2262 unsigned long bsec,bnsec;
2263 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002264#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002265 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002266#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002267 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002268#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002269 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002270 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2271 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002272 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002273#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002274#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002275 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2276 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002277#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002278#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2279 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2280 PyLong_FromUnsignedLong(st->st_file_attributes));
2281#endif
jcea6c51d512018-01-28 14:00:08 +01002282#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2283 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2284 PyUnicode_FromString(st->st_fstype));
2285#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002286#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2287 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2288 PyLong_FromUnsignedLong(st->st_reparse_tag));
2289#endif
Fred Drake699f3522000-06-29 21:12:41 +00002290
Victor Stinner8c62be82010-05-06 00:08:46 +00002291 if (PyErr_Occurred()) {
2292 Py_DECREF(v);
2293 return NULL;
2294 }
Fred Drake699f3522000-06-29 21:12:41 +00002295
Victor Stinner8c62be82010-05-06 00:08:46 +00002296 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002297}
2298
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002299/* POSIX methods */
2300
Guido van Rossum94f6f721999-01-06 18:42:14 +00002301
2302static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02002303posix_do_stat(PyObject *module, const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002304 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002305{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002306 STRUCT_STAT st;
2307 int result;
2308
2309#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2310 if (follow_symlinks_specified(function_name, follow_symlinks))
2311 return NULL;
2312#endif
2313
2314 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2315 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2316 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2317 return NULL;
2318
2319 Py_BEGIN_ALLOW_THREADS
2320 if (path->fd != -1)
2321 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002322#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002323 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002324 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002325 else
Steve Dowercc16be82016-09-08 10:35:16 -07002326 result = win32_lstat(path->wide, &st);
2327#else
2328 else
2329#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002330 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2331 result = LSTAT(path->narrow, &st);
2332 else
Steve Dowercc16be82016-09-08 10:35:16 -07002333#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002334#ifdef HAVE_FSTATAT
2335 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2336 result = fstatat(dir_fd, path->narrow, &st,
2337 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2338 else
Steve Dowercc16be82016-09-08 10:35:16 -07002339#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002340 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002341#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002342 Py_END_ALLOW_THREADS
2343
Victor Stinner292c8352012-10-30 02:17:38 +01002344 if (result != 0) {
2345 return path_error(path);
2346 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002347
Victor Stinner1c2fa782020-05-10 11:05:29 +02002348 return _pystat_fromstructstat(module, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002349}
2350
Larry Hastings2f936352014-08-05 14:04:04 +10002351/*[python input]
2352
2353for s in """
2354
2355FACCESSAT
2356FCHMODAT
2357FCHOWNAT
2358FSTATAT
2359LINKAT
2360MKDIRAT
2361MKFIFOAT
2362MKNODAT
2363OPENAT
2364READLINKAT
2365SYMLINKAT
2366UNLINKAT
2367
2368""".strip().split():
2369 s = s.strip()
2370 print("""
2371#ifdef HAVE_{s}
2372 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002373#else
Larry Hastings2f936352014-08-05 14:04:04 +10002374 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002375#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002376""".rstrip().format(s=s))
2377
2378for s in """
2379
2380FCHDIR
2381FCHMOD
2382FCHOWN
2383FDOPENDIR
2384FEXECVE
2385FPATHCONF
2386FSTATVFS
2387FTRUNCATE
2388
2389""".strip().split():
2390 s = s.strip()
2391 print("""
2392#ifdef HAVE_{s}
2393 #define PATH_HAVE_{s} 1
2394#else
2395 #define PATH_HAVE_{s} 0
2396#endif
2397
2398""".rstrip().format(s=s))
2399[python start generated code]*/
2400
2401#ifdef HAVE_FACCESSAT
2402 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2403#else
2404 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2405#endif
2406
2407#ifdef HAVE_FCHMODAT
2408 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2409#else
2410 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2411#endif
2412
2413#ifdef HAVE_FCHOWNAT
2414 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2415#else
2416 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2417#endif
2418
2419#ifdef HAVE_FSTATAT
2420 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2421#else
2422 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2423#endif
2424
2425#ifdef HAVE_LINKAT
2426 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2427#else
2428 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2429#endif
2430
2431#ifdef HAVE_MKDIRAT
2432 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2433#else
2434 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2435#endif
2436
2437#ifdef HAVE_MKFIFOAT
2438 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2439#else
2440 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2441#endif
2442
2443#ifdef HAVE_MKNODAT
2444 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2445#else
2446 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2447#endif
2448
2449#ifdef HAVE_OPENAT
2450 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2451#else
2452 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2453#endif
2454
2455#ifdef HAVE_READLINKAT
2456 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2457#else
2458 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2459#endif
2460
2461#ifdef HAVE_SYMLINKAT
2462 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2463#else
2464 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2465#endif
2466
2467#ifdef HAVE_UNLINKAT
2468 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2469#else
2470 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2471#endif
2472
2473#ifdef HAVE_FCHDIR
2474 #define PATH_HAVE_FCHDIR 1
2475#else
2476 #define PATH_HAVE_FCHDIR 0
2477#endif
2478
2479#ifdef HAVE_FCHMOD
2480 #define PATH_HAVE_FCHMOD 1
2481#else
2482 #define PATH_HAVE_FCHMOD 0
2483#endif
2484
2485#ifdef HAVE_FCHOWN
2486 #define PATH_HAVE_FCHOWN 1
2487#else
2488 #define PATH_HAVE_FCHOWN 0
2489#endif
2490
2491#ifdef HAVE_FDOPENDIR
2492 #define PATH_HAVE_FDOPENDIR 1
2493#else
2494 #define PATH_HAVE_FDOPENDIR 0
2495#endif
2496
2497#ifdef HAVE_FEXECVE
2498 #define PATH_HAVE_FEXECVE 1
2499#else
2500 #define PATH_HAVE_FEXECVE 0
2501#endif
2502
2503#ifdef HAVE_FPATHCONF
2504 #define PATH_HAVE_FPATHCONF 1
2505#else
2506 #define PATH_HAVE_FPATHCONF 0
2507#endif
2508
2509#ifdef HAVE_FSTATVFS
2510 #define PATH_HAVE_FSTATVFS 1
2511#else
2512 #define PATH_HAVE_FSTATVFS 0
2513#endif
2514
2515#ifdef HAVE_FTRUNCATE
2516 #define PATH_HAVE_FTRUNCATE 1
2517#else
2518 #define PATH_HAVE_FTRUNCATE 0
2519#endif
2520/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002521
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002522#ifdef MS_WINDOWS
2523 #undef PATH_HAVE_FTRUNCATE
2524 #define PATH_HAVE_FTRUNCATE 1
2525#endif
Larry Hastings31826802013-10-19 00:09:25 -07002526
Larry Hastings61272b72014-01-07 12:41:53 -08002527/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002528
2529class path_t_converter(CConverter):
2530
2531 type = "path_t"
2532 impl_by_reference = True
2533 parse_by_reference = True
2534
2535 converter = 'path_converter'
2536
2537 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002538 # right now path_t doesn't support default values.
2539 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002540 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002541 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002542
Larry Hastings2f936352014-08-05 14:04:04 +10002543 if self.c_default not in (None, 'Py_None'):
2544 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002545
2546 self.nullable = nullable
2547 self.allow_fd = allow_fd
2548
Larry Hastings7726ac92014-01-31 22:03:12 -08002549 def pre_render(self):
2550 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002551 if isinstance(value, str):
2552 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002553 return str(int(bool(value)))
2554
2555 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002556 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002557 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002558 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002559 strify(self.nullable),
2560 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002561 )
2562
2563 def cleanup(self):
2564 return "path_cleanup(&" + self.name + ");\n"
2565
2566
2567class dir_fd_converter(CConverter):
2568 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002569
Larry Hastings2f936352014-08-05 14:04:04 +10002570 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002571 if self.default in (unspecified, None):
2572 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002573 if isinstance(requires, str):
2574 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2575 else:
2576 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002577
Larry Hastings2f936352014-08-05 14:04:04 +10002578class fildes_converter(CConverter):
2579 type = 'int'
2580 converter = 'fildes_converter'
2581
2582class uid_t_converter(CConverter):
2583 type = "uid_t"
2584 converter = '_Py_Uid_Converter'
2585
2586class gid_t_converter(CConverter):
2587 type = "gid_t"
2588 converter = '_Py_Gid_Converter'
2589
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002590class dev_t_converter(CConverter):
2591 type = 'dev_t'
2592 converter = '_Py_Dev_Converter'
2593
2594class dev_t_return_converter(unsigned_long_return_converter):
2595 type = 'dev_t'
2596 conversion_fn = '_PyLong_FromDev'
2597 unsigned_cast = '(dev_t)'
2598
Larry Hastings2f936352014-08-05 14:04:04 +10002599class FSConverter_converter(CConverter):
2600 type = 'PyObject *'
2601 converter = 'PyUnicode_FSConverter'
2602 def converter_init(self):
2603 if self.default is not unspecified:
2604 fail("FSConverter_converter does not support default values")
2605 self.c_default = 'NULL'
2606
2607 def cleanup(self):
2608 return "Py_XDECREF(" + self.name + ");\n"
2609
2610class pid_t_converter(CConverter):
2611 type = 'pid_t'
2612 format_unit = '" _Py_PARSE_PID "'
2613
2614class idtype_t_converter(int_converter):
2615 type = 'idtype_t'
2616
2617class id_t_converter(CConverter):
2618 type = 'id_t'
2619 format_unit = '" _Py_PARSE_PID "'
2620
Benjamin Petersonca470632016-09-06 13:47:26 -07002621class intptr_t_converter(CConverter):
2622 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002623 format_unit = '" _Py_PARSE_INTPTR "'
2624
2625class Py_off_t_converter(CConverter):
2626 type = 'Py_off_t'
2627 converter = 'Py_off_t_converter'
2628
2629class Py_off_t_return_converter(long_return_converter):
2630 type = 'Py_off_t'
2631 conversion_fn = 'PyLong_FromPy_off_t'
2632
2633class path_confname_converter(CConverter):
2634 type="int"
2635 converter="conv_path_confname"
2636
2637class confstr_confname_converter(path_confname_converter):
2638 converter='conv_confstr_confname'
2639
2640class sysconf_confname_converter(path_confname_converter):
2641 converter="conv_sysconf_confname"
2642
Larry Hastings61272b72014-01-07 12:41:53 -08002643[python start generated code]*/
Victor Stinner1c2fa782020-05-10 11:05:29 +02002644/*[python end generated code: output=da39a3ee5e6b4b0d input=f1c8ae8d744f6c8b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002645
Larry Hastings61272b72014-01-07 12:41:53 -08002646/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002647
Larry Hastings2a727912014-01-16 11:32:01 -08002648os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002649
2650 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002651 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002652 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002653
2654 *
2655
Larry Hastings2f936352014-08-05 14:04:04 +10002656 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002657 If not None, it should be a file descriptor open to a directory,
2658 and path should be a relative string; path will then be relative to
2659 that directory.
2660
2661 follow_symlinks: bool = True
2662 If False, and the last element of the path is a symbolic link,
2663 stat will examine the symbolic link itself instead of the file
2664 the link points to.
2665
2666Perform a stat system call on the given path.
2667
2668dir_fd and follow_symlinks may not be implemented
2669 on your platform. If they are unavailable, using them will raise a
2670 NotImplementedError.
2671
2672It's an error to use dir_fd or follow_symlinks when specifying path as
2673 an open file descriptor.
2674
Larry Hastings61272b72014-01-07 12:41:53 -08002675[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002676
Larry Hastings31826802013-10-19 00:09:25 -07002677static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002678os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002679/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002680{
Victor Stinner1c2fa782020-05-10 11:05:29 +02002681 return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002682}
2683
Larry Hastings2f936352014-08-05 14:04:04 +10002684
2685/*[clinic input]
2686os.lstat
2687
2688 path : path_t
2689
2690 *
2691
2692 dir_fd : dir_fd(requires='fstatat') = None
2693
2694Perform a stat system call on the given path, without following symbolic links.
2695
2696Like stat(), but do not follow symbolic links.
2697Equivalent to stat(path, follow_symlinks=False).
2698[clinic start generated code]*/
2699
Larry Hastings2f936352014-08-05 14:04:04 +10002700static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002701os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2702/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002703{
2704 int follow_symlinks = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002705 return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10002706}
Larry Hastings31826802013-10-19 00:09:25 -07002707
Larry Hastings2f936352014-08-05 14:04:04 +10002708
Larry Hastings61272b72014-01-07 12:41:53 -08002709/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002710os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002711
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002712 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002713 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002714
2715 mode: int
2716 Operating-system mode bitfield. Can be F_OK to test existence,
2717 or the inclusive-OR of R_OK, W_OK, and X_OK.
2718
2719 *
2720
Larry Hastings2f936352014-08-05 14:04:04 +10002721 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002722 If not None, it should be a file descriptor open to a directory,
2723 and path should be relative; path will then be relative to that
2724 directory.
2725
2726 effective_ids: bool = False
2727 If True, access will use the effective uid/gid instead of
2728 the real uid/gid.
2729
2730 follow_symlinks: bool = True
2731 If False, and the last element of the path is a symbolic link,
2732 access will examine the symbolic link itself instead of the file
2733 the link points to.
2734
2735Use the real uid/gid to test for access to a path.
2736
2737{parameters}
2738dir_fd, effective_ids, and follow_symlinks may not be implemented
2739 on your platform. If they are unavailable, using them will raise a
2740 NotImplementedError.
2741
2742Note that most operations will use the effective uid/gid, therefore this
2743 routine can be used in a suid/sgid environment to test if the invoking user
2744 has the specified access to the path.
2745
Larry Hastings61272b72014-01-07 12:41:53 -08002746[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002747
Larry Hastings2f936352014-08-05 14:04:04 +10002748static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002749os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002750 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002751/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002752{
Larry Hastings2f936352014-08-05 14:04:04 +10002753 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002754
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002755#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002756 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002757#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002758 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002759#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002760
Larry Hastings9cf065c2012-06-22 16:30:09 -07002761#ifndef HAVE_FACCESSAT
2762 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002763 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002764
2765 if (effective_ids) {
2766 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002767 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002768 }
2769#endif
2770
2771#ifdef MS_WINDOWS
2772 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002773 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002774 Py_END_ALLOW_THREADS
2775
2776 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002777 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002778 * * we didn't get a -1, and
2779 * * write access wasn't requested,
2780 * * or the file isn't read-only,
2781 * * or it's a directory.
2782 * (Directories cannot be read-only on Windows.)
2783 */
Larry Hastings2f936352014-08-05 14:04:04 +10002784 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002785 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002786 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002787 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788#else
2789
2790 Py_BEGIN_ALLOW_THREADS
2791#ifdef HAVE_FACCESSAT
2792 if ((dir_fd != DEFAULT_DIR_FD) ||
2793 effective_ids ||
2794 !follow_symlinks) {
2795 int flags = 0;
2796 if (!follow_symlinks)
2797 flags |= AT_SYMLINK_NOFOLLOW;
2798 if (effective_ids)
2799 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002800 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002801 }
2802 else
2803#endif
Larry Hastings31826802013-10-19 00:09:25 -07002804 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002805 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002806 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002807#endif
2808
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002810}
2811
Guido van Rossumd371ff11999-01-25 16:12:23 +00002812#ifndef F_OK
2813#define F_OK 0
2814#endif
2815#ifndef R_OK
2816#define R_OK 4
2817#endif
2818#ifndef W_OK
2819#define W_OK 2
2820#endif
2821#ifndef X_OK
2822#define X_OK 1
2823#endif
2824
Larry Hastings31826802013-10-19 00:09:25 -07002825
Guido van Rossumd371ff11999-01-25 16:12:23 +00002826#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002827/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002828os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002829
2830 fd: int
2831 Integer file descriptor handle.
2832
2833 /
2834
2835Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002836[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002837
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002838static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002839os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002840/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002841{
Guido van Rossum94f6f721999-01-06 18:42:14 +00002842
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002843 long size = sysconf(_SC_TTY_NAME_MAX);
2844 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002845 return posix_error();
2846 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002847 char *buffer = (char *)PyMem_RawMalloc(size);
2848 if (buffer == NULL) {
2849 return PyErr_NoMemory();
2850 }
2851 int ret = ttyname_r(fd, buffer, size);
2852 if (ret != 0) {
2853 PyMem_RawFree(buffer);
2854 errno = ret;
2855 return posix_error();
2856 }
2857 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
2858 PyMem_RawFree(buffer);
2859 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002860}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002861#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002862
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002863#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002864/*[clinic input]
2865os.ctermid
2866
2867Return the name of the controlling terminal for this process.
2868[clinic start generated code]*/
2869
Larry Hastings2f936352014-08-05 14:04:04 +10002870static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002871os_ctermid_impl(PyObject *module)
2872/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002873{
Victor Stinner8c62be82010-05-06 00:08:46 +00002874 char *ret;
2875 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002876
Greg Wardb48bc172000-03-01 21:51:56 +00002877#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002878 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002879#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002880 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002881#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002882 if (ret == NULL)
2883 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002884 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002885}
Larry Hastings2f936352014-08-05 14:04:04 +10002886#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002887
Larry Hastings2f936352014-08-05 14:04:04 +10002888
2889/*[clinic input]
2890os.chdir
2891
2892 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2893
2894Change the current working directory to the specified path.
2895
2896path may always be specified as a string.
2897On some platforms, path may also be specified as an open file descriptor.
2898 If this functionality is unavailable, using it raises an exception.
2899[clinic start generated code]*/
2900
Larry Hastings2f936352014-08-05 14:04:04 +10002901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002902os_chdir_impl(PyObject *module, path_t *path)
2903/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002904{
2905 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002906
Saiyang Gou7514f4f2020-02-12 23:47:42 -08002907 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
2908 return NULL;
2909 }
2910
Larry Hastings9cf065c2012-06-22 16:30:09 -07002911 Py_BEGIN_ALLOW_THREADS
2912#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002913 /* on unix, success = 0, on windows, success = !0 */
2914 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002915#else
2916#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002917 if (path->fd != -1)
2918 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002919 else
2920#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002921 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002922#endif
2923 Py_END_ALLOW_THREADS
2924
2925 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002926 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002927 }
2928
Larry Hastings2f936352014-08-05 14:04:04 +10002929 Py_RETURN_NONE;
2930}
2931
2932
2933#ifdef HAVE_FCHDIR
2934/*[clinic input]
2935os.fchdir
2936
2937 fd: fildes
2938
2939Change to the directory of the given file descriptor.
2940
2941fd must be opened on a directory, not a file.
2942Equivalent to os.chdir(fd).
2943
2944[clinic start generated code]*/
2945
Fred Drake4d1e64b2002-04-15 19:40:07 +00002946static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002947os_fchdir_impl(PyObject *module, int fd)
2948/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002949{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08002950 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
2951 return NULL;
2952 }
Larry Hastings2f936352014-08-05 14:04:04 +10002953 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002954}
2955#endif /* HAVE_FCHDIR */
2956
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002957
Larry Hastings2f936352014-08-05 14:04:04 +10002958/*[clinic input]
2959os.chmod
2960
2961 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002962 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002963 On some platforms, path may also be specified as an open file descriptor.
2964 If this functionality is unavailable, using it raises an exception.
2965
2966 mode: int
2967 Operating-system mode bitfield.
2968
2969 *
2970
2971 dir_fd : dir_fd(requires='fchmodat') = None
2972 If not None, it should be a file descriptor open to a directory,
2973 and path should be relative; path will then be relative to that
2974 directory.
2975
2976 follow_symlinks: bool = True
2977 If False, and the last element of the path is a symbolic link,
2978 chmod will modify the symbolic link itself instead of the file
2979 the link points to.
2980
2981Change the access permissions of a file.
2982
2983It is an error to use dir_fd or follow_symlinks when specifying path as
2984 an open file descriptor.
2985dir_fd and follow_symlinks may not be implemented on your platform.
2986 If they are unavailable, using them will raise a NotImplementedError.
2987
2988[clinic start generated code]*/
2989
Larry Hastings2f936352014-08-05 14:04:04 +10002990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002991os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002992 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002993/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002994{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002995 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002996
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002997#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002998 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002999#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003000
Larry Hastings9cf065c2012-06-22 16:30:09 -07003001#ifdef HAVE_FCHMODAT
3002 int fchmodat_nofollow_unsupported = 0;
3003#endif
3004
Larry Hastings9cf065c2012-06-22 16:30:09 -07003005#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3006 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003007 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003008#endif
3009
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003010 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3011 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3012 return NULL;
3013 }
3014
Larry Hastings9cf065c2012-06-22 16:30:09 -07003015#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003016 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003017 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003018 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003019 result = 0;
3020 else {
3021 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003022 attr &= ~FILE_ATTRIBUTE_READONLY;
3023 else
3024 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003025 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003026 }
3027 Py_END_ALLOW_THREADS
3028
3029 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003030 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003031 }
3032#else /* MS_WINDOWS */
3033 Py_BEGIN_ALLOW_THREADS
3034#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003035 if (path->fd != -1)
3036 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003037 else
3038#endif
3039#ifdef HAVE_LCHMOD
3040 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003041 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003042 else
3043#endif
3044#ifdef HAVE_FCHMODAT
3045 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3046 /*
3047 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3048 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003049 * and then says it isn't implemented yet.
3050 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003051 *
3052 * Once it is supported, os.chmod will automatically
3053 * support dir_fd and follow_symlinks=False. (Hopefully.)
3054 * Until then, we need to be careful what exception we raise.
3055 */
Larry Hastings2f936352014-08-05 14:04:04 +10003056 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003057 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3058 /*
3059 * But wait! We can't throw the exception without allowing threads,
3060 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3061 */
3062 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003063 result &&
3064 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3065 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003066 }
3067 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003068#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003069 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003070 Py_END_ALLOW_THREADS
3071
3072 if (result) {
3073#ifdef HAVE_FCHMODAT
3074 if (fchmodat_nofollow_unsupported) {
3075 if (dir_fd != DEFAULT_DIR_FD)
3076 dir_fd_and_follow_symlinks_invalid("chmod",
3077 dir_fd, follow_symlinks);
3078 else
3079 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003080 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003081 }
3082 else
3083#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003084 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003085 }
3086#endif
3087
Larry Hastings2f936352014-08-05 14:04:04 +10003088 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003089}
3090
Larry Hastings9cf065c2012-06-22 16:30:09 -07003091
Christian Heimes4e30a842007-11-30 22:12:06 +00003092#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003093/*[clinic input]
3094os.fchmod
3095
3096 fd: int
3097 mode: int
3098
3099Change the access permissions of the file given by file descriptor fd.
3100
3101Equivalent to os.chmod(fd, mode).
3102[clinic start generated code]*/
3103
Larry Hastings2f936352014-08-05 14:04:04 +10003104static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003105os_fchmod_impl(PyObject *module, int fd, int mode)
3106/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003107{
3108 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003109 int async_err = 0;
3110
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003111 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3112 return NULL;
3113 }
3114
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003115 do {
3116 Py_BEGIN_ALLOW_THREADS
3117 res = fchmod(fd, mode);
3118 Py_END_ALLOW_THREADS
3119 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3120 if (res != 0)
3121 return (!async_err) ? posix_error() : NULL;
3122
Victor Stinner8c62be82010-05-06 00:08:46 +00003123 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003124}
3125#endif /* HAVE_FCHMOD */
3126
Larry Hastings2f936352014-08-05 14:04:04 +10003127
Christian Heimes4e30a842007-11-30 22:12:06 +00003128#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003129/*[clinic input]
3130os.lchmod
3131
3132 path: path_t
3133 mode: int
3134
3135Change the access permissions of a file, without following symbolic links.
3136
3137If path is a symlink, this affects the link itself rather than the target.
3138Equivalent to chmod(path, mode, follow_symlinks=False)."
3139[clinic start generated code]*/
3140
Larry Hastings2f936352014-08-05 14:04:04 +10003141static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003142os_lchmod_impl(PyObject *module, path_t *path, int mode)
3143/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003144{
Victor Stinner8c62be82010-05-06 00:08:46 +00003145 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003146 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3147 return NULL;
3148 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003149 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003150 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003151 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003152 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003153 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003154 return NULL;
3155 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003157}
3158#endif /* HAVE_LCHMOD */
3159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003160
Thomas Wouterscf297e42007-02-23 15:07:44 +00003161#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003162/*[clinic input]
3163os.chflags
3164
3165 path: path_t
3166 flags: unsigned_long(bitwise=True)
3167 follow_symlinks: bool=True
3168
3169Set file flags.
3170
3171If follow_symlinks is False, and the last element of the path is a symbolic
3172 link, chflags will change flags on the symbolic link itself instead of the
3173 file the link points to.
3174follow_symlinks may not be implemented on your platform. If it is
3175unavailable, using it will raise a NotImplementedError.
3176
3177[clinic start generated code]*/
3178
Larry Hastings2f936352014-08-05 14:04:04 +10003179static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003180os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003181 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003182/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003183{
3184 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003185
3186#ifndef HAVE_LCHFLAGS
3187 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003188 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003189#endif
3190
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003191 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3192 return NULL;
3193 }
3194
Victor Stinner8c62be82010-05-06 00:08:46 +00003195 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003196#ifdef HAVE_LCHFLAGS
3197 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003198 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003199 else
3200#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003201 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003202 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003203
Larry Hastings2f936352014-08-05 14:04:04 +10003204 if (result)
3205 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003206
Larry Hastings2f936352014-08-05 14:04:04 +10003207 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003208}
3209#endif /* HAVE_CHFLAGS */
3210
Larry Hastings2f936352014-08-05 14:04:04 +10003211
Thomas Wouterscf297e42007-02-23 15:07:44 +00003212#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003213/*[clinic input]
3214os.lchflags
3215
3216 path: path_t
3217 flags: unsigned_long(bitwise=True)
3218
3219Set file flags.
3220
3221This function will not follow symbolic links.
3222Equivalent to chflags(path, flags, follow_symlinks=False).
3223[clinic start generated code]*/
3224
Larry Hastings2f936352014-08-05 14:04:04 +10003225static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003226os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3227/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003228{
Victor Stinner8c62be82010-05-06 00:08:46 +00003229 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003230 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3231 return NULL;
3232 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003233 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003234 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003236 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003237 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003238 }
Victor Stinner292c8352012-10-30 02:17:38 +01003239 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003240}
3241#endif /* HAVE_LCHFLAGS */
3242
Larry Hastings2f936352014-08-05 14:04:04 +10003243
Martin v. Löwis244edc82001-10-04 22:44:26 +00003244#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003245/*[clinic input]
3246os.chroot
3247 path: path_t
3248
3249Change root directory to path.
3250
3251[clinic start generated code]*/
3252
Larry Hastings2f936352014-08-05 14:04:04 +10003253static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003254os_chroot_impl(PyObject *module, path_t *path)
3255/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003256{
3257 int res;
3258 Py_BEGIN_ALLOW_THREADS
3259 res = chroot(path->narrow);
3260 Py_END_ALLOW_THREADS
3261 if (res < 0)
3262 return path_error(path);
3263 Py_RETURN_NONE;
3264}
3265#endif /* HAVE_CHROOT */
3266
Martin v. Löwis244edc82001-10-04 22:44:26 +00003267
Guido van Rossum21142a01999-01-08 21:05:37 +00003268#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003269/*[clinic input]
3270os.fsync
3271
3272 fd: fildes
3273
3274Force write of fd to disk.
3275[clinic start generated code]*/
3276
Larry Hastings2f936352014-08-05 14:04:04 +10003277static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003278os_fsync_impl(PyObject *module, int fd)
3279/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003280{
3281 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003282}
3283#endif /* HAVE_FSYNC */
3284
Larry Hastings2f936352014-08-05 14:04:04 +10003285
Ross Lagerwall7807c352011-03-17 20:20:30 +02003286#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003287/*[clinic input]
3288os.sync
3289
3290Force write of everything to disk.
3291[clinic start generated code]*/
3292
Larry Hastings2f936352014-08-05 14:04:04 +10003293static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003294os_sync_impl(PyObject *module)
3295/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003296{
3297 Py_BEGIN_ALLOW_THREADS
3298 sync();
3299 Py_END_ALLOW_THREADS
3300 Py_RETURN_NONE;
3301}
Larry Hastings2f936352014-08-05 14:04:04 +10003302#endif /* HAVE_SYNC */
3303
Ross Lagerwall7807c352011-03-17 20:20:30 +02003304
Guido van Rossum21142a01999-01-08 21:05:37 +00003305#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003306#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003307extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3308#endif
3309
Larry Hastings2f936352014-08-05 14:04:04 +10003310/*[clinic input]
3311os.fdatasync
3312
3313 fd: fildes
3314
3315Force write of fd to disk without forcing update of metadata.
3316[clinic start generated code]*/
3317
Larry Hastings2f936352014-08-05 14:04:04 +10003318static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003319os_fdatasync_impl(PyObject *module, int fd)
3320/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003321{
3322 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003323}
3324#endif /* HAVE_FDATASYNC */
3325
3326
Fredrik Lundh10723342000-07-10 16:38:09 +00003327#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003328/*[clinic input]
3329os.chown
3330
3331 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003332 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003333
3334 uid: uid_t
3335
3336 gid: gid_t
3337
3338 *
3339
3340 dir_fd : dir_fd(requires='fchownat') = None
3341 If not None, it should be a file descriptor open to a directory,
3342 and path should be relative; path will then be relative to that
3343 directory.
3344
3345 follow_symlinks: bool = True
3346 If False, and the last element of the path is a symbolic link,
3347 stat will examine the symbolic link itself instead of the file
3348 the link points to.
3349
3350Change the owner and group id of path to the numeric uid and gid.\
3351
3352path may always be specified as a string.
3353On some platforms, path may also be specified as an open file descriptor.
3354 If this functionality is unavailable, using it raises an exception.
3355If dir_fd is not None, it should be a file descriptor open to a directory,
3356 and path should be relative; path will then be relative to that directory.
3357If follow_symlinks is False, and the last element of the path is a symbolic
3358 link, chown will modify the symbolic link itself instead of the file the
3359 link points to.
3360It is an error to use dir_fd or follow_symlinks when specifying path as
3361 an open file descriptor.
3362dir_fd and follow_symlinks may not be implemented on your platform.
3363 If they are unavailable, using them will raise a NotImplementedError.
3364
3365[clinic start generated code]*/
3366
Larry Hastings2f936352014-08-05 14:04:04 +10003367static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003368os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003369 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003370/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003371{
3372 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373
3374#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3375 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003376 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003377#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003378 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3379 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3380 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003381
3382#ifdef __APPLE__
3383 /*
3384 * This is for Mac OS X 10.3, which doesn't have lchown.
3385 * (But we still have an lchown symbol because of weak-linking.)
3386 * It doesn't have fchownat either. So there's no possibility
3387 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003388 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003389 if ((!follow_symlinks) && (lchown == NULL)) {
3390 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003391 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392 }
3393#endif
3394
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003395 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3396 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3397 return NULL;
3398 }
3399
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003401#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003402 if (path->fd != -1)
3403 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003404 else
3405#endif
3406#ifdef HAVE_LCHOWN
3407 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003408 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003409 else
3410#endif
3411#ifdef HAVE_FCHOWNAT
3412 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003413 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003414 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3415 else
3416#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003417 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003419
Larry Hastings2f936352014-08-05 14:04:04 +10003420 if (result)
3421 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422
Larry Hastings2f936352014-08-05 14:04:04 +10003423 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003424}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003425#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003426
Larry Hastings2f936352014-08-05 14:04:04 +10003427
Christian Heimes4e30a842007-11-30 22:12:06 +00003428#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003429/*[clinic input]
3430os.fchown
3431
3432 fd: int
3433 uid: uid_t
3434 gid: gid_t
3435
3436Change the owner and group id of the file specified by file descriptor.
3437
3438Equivalent to os.chown(fd, uid, gid).
3439
3440[clinic start generated code]*/
3441
Larry Hastings2f936352014-08-05 14:04:04 +10003442static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003443os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3444/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003445{
Victor Stinner8c62be82010-05-06 00:08:46 +00003446 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003447 int async_err = 0;
3448
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003449 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3450 return NULL;
3451 }
3452
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003453 do {
3454 Py_BEGIN_ALLOW_THREADS
3455 res = fchown(fd, uid, gid);
3456 Py_END_ALLOW_THREADS
3457 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3458 if (res != 0)
3459 return (!async_err) ? posix_error() : NULL;
3460
Victor Stinner8c62be82010-05-06 00:08:46 +00003461 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003462}
3463#endif /* HAVE_FCHOWN */
3464
Larry Hastings2f936352014-08-05 14:04:04 +10003465
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003466#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003467/*[clinic input]
3468os.lchown
3469
3470 path : path_t
3471 uid: uid_t
3472 gid: gid_t
3473
3474Change the owner and group id of path to the numeric uid and gid.
3475
3476This function will not follow symbolic links.
3477Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3478[clinic start generated code]*/
3479
Larry Hastings2f936352014-08-05 14:04:04 +10003480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003481os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3482/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003483{
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003485 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3486 return NULL;
3487 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003489 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003491 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003492 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003493 }
Larry Hastings2f936352014-08-05 14:04:04 +10003494 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003495}
3496#endif /* HAVE_LCHOWN */
3497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003498
Barry Warsaw53699e91996-12-10 23:23:01 +00003499static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003500posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003501{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003502#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003503 wchar_t wbuf[MAXPATHLEN];
3504 wchar_t *wbuf2 = wbuf;
3505 DWORD len;
3506
3507 Py_BEGIN_ALLOW_THREADS
3508 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3509 /* If the buffer is large enough, len does not include the
3510 terminating \0. If the buffer is too small, len includes
3511 the space needed for the terminator. */
3512 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003513 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003514 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003515 }
Victor Stinner689830e2019-06-26 17:31:12 +02003516 else {
3517 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003518 }
Victor Stinner689830e2019-06-26 17:31:12 +02003519 if (wbuf2) {
3520 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 }
Victor Stinner689830e2019-06-26 17:31:12 +02003522 }
3523 Py_END_ALLOW_THREADS
3524
3525 if (!wbuf2) {
3526 PyErr_NoMemory();
3527 return NULL;
3528 }
3529 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003530 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003531 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003532 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003533 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003534
Victor Stinner689830e2019-06-26 17:31:12 +02003535 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3536 if (wbuf2 != wbuf) {
3537 PyMem_RawFree(wbuf2);
3538 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003539
Victor Stinner689830e2019-06-26 17:31:12 +02003540 if (use_bytes) {
3541 if (resobj == NULL) {
3542 return NULL;
3543 }
3544 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3545 }
3546
3547 return resobj;
3548#else
3549 const size_t chunk = 1024;
3550
3551 char *buf = NULL;
3552 char *cwd = NULL;
3553 size_t buflen = 0;
3554
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003556 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003557 char *newbuf;
3558 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3559 buflen += chunk;
3560 newbuf = PyMem_RawRealloc(buf, buflen);
3561 }
3562 else {
3563 newbuf = NULL;
3564 }
3565 if (newbuf == NULL) {
3566 PyMem_RawFree(buf);
3567 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003568 break;
3569 }
Victor Stinner689830e2019-06-26 17:31:12 +02003570 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003571
Victor Stinner4403d7d2015-04-25 00:16:10 +02003572 cwd = getcwd(buf, buflen);
3573 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003575
Victor Stinner689830e2019-06-26 17:31:12 +02003576 if (buf == NULL) {
3577 return PyErr_NoMemory();
3578 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003579 if (cwd == NULL) {
3580 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003581 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003582 }
3583
Victor Stinner689830e2019-06-26 17:31:12 +02003584 PyObject *obj;
3585 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003586 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003587 }
3588 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003589 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003590 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003591 PyMem_RawFree(buf);
3592
3593 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003594#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003595}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003596
Larry Hastings2f936352014-08-05 14:04:04 +10003597
3598/*[clinic input]
3599os.getcwd
3600
3601Return a unicode string representing the current working directory.
3602[clinic start generated code]*/
3603
Larry Hastings2f936352014-08-05 14:04:04 +10003604static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003605os_getcwd_impl(PyObject *module)
3606/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003607{
3608 return posix_getcwd(0);
3609}
3610
Larry Hastings2f936352014-08-05 14:04:04 +10003611
3612/*[clinic input]
3613os.getcwdb
3614
3615Return a bytes string representing the current working directory.
3616[clinic start generated code]*/
3617
Larry Hastings2f936352014-08-05 14:04:04 +10003618static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003619os_getcwdb_impl(PyObject *module)
3620/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003621{
3622 return posix_getcwd(1);
3623}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003624
Larry Hastings2f936352014-08-05 14:04:04 +10003625
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3627#define HAVE_LINK 1
3628#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003629
Guido van Rossumb6775db1994-08-01 11:34:53 +00003630#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003631/*[clinic input]
3632
3633os.link
3634
3635 src : path_t
3636 dst : path_t
3637 *
3638 src_dir_fd : dir_fd = None
3639 dst_dir_fd : dir_fd = None
3640 follow_symlinks: bool = True
3641
3642Create a hard link to a file.
3643
3644If either src_dir_fd or dst_dir_fd is not None, it should be a file
3645 descriptor open to a directory, and the respective path string (src or dst)
3646 should be relative; the path will then be relative to that directory.
3647If follow_symlinks is False, and the last element of src is a symbolic
3648 link, link will create a link to the symbolic link itself instead of the
3649 file the link points to.
3650src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3651 platform. If they are unavailable, using them will raise a
3652 NotImplementedError.
3653[clinic start generated code]*/
3654
Larry Hastings2f936352014-08-05 14:04:04 +10003655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003656os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003657 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003658/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003659{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003660#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003661 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003662#else
3663 int result;
3664#endif
3665
Larry Hastings9cf065c2012-06-22 16:30:09 -07003666#ifndef HAVE_LINKAT
3667 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3668 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003669 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003670 }
3671#endif
3672
Steve Dowercc16be82016-09-08 10:35:16 -07003673#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003674 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003675 PyErr_SetString(PyExc_NotImplementedError,
3676 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003677 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003678 }
Steve Dowercc16be82016-09-08 10:35:16 -07003679#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003680
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003681 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3682 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3683 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3684 return NULL;
3685 }
3686
Brian Curtin1b9df392010-11-24 20:24:31 +00003687#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003688 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003689 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003690 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003691
Larry Hastings2f936352014-08-05 14:04:04 +10003692 if (!result)
3693 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003694#else
3695 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003696#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003697 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3698 (dst_dir_fd != DEFAULT_DIR_FD) ||
3699 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003700 result = linkat(src_dir_fd, src->narrow,
3701 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003702 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3703 else
Steve Dowercc16be82016-09-08 10:35:16 -07003704#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003705 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003706 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003707
Larry Hastings2f936352014-08-05 14:04:04 +10003708 if (result)
3709 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003710#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003711
Larry Hastings2f936352014-08-05 14:04:04 +10003712 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003713}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003714#endif
3715
Brian Curtin1b9df392010-11-24 20:24:31 +00003716
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003717#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003718static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003719_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003720{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003721 PyObject *v;
3722 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3723 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003724 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003725 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003726 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003727 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728
Steve Dowercc16be82016-09-08 10:35:16 -07003729 WIN32_FIND_DATAW wFileData;
3730 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003731
Steve Dowercc16be82016-09-08 10:35:16 -07003732 if (!path->wide) { /* Default arg: "." */
3733 po_wchars = L".";
3734 len = 1;
3735 } else {
3736 po_wchars = path->wide;
3737 len = wcslen(path->wide);
3738 }
3739 /* The +5 is so we can append "\\*.*\0" */
3740 wnamebuf = PyMem_New(wchar_t, len + 5);
3741 if (!wnamebuf) {
3742 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003743 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003744 }
Steve Dowercc16be82016-09-08 10:35:16 -07003745 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003746 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003747 wchar_t wch = wnamebuf[len-1];
3748 if (wch != SEP && wch != ALTSEP && wch != L':')
3749 wnamebuf[len++] = SEP;
3750 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003751 }
Steve Dowercc16be82016-09-08 10:35:16 -07003752 if ((list = PyList_New(0)) == NULL) {
3753 goto exit;
3754 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003755 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003756 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003757 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003758 if (hFindFile == INVALID_HANDLE_VALUE) {
3759 int error = GetLastError();
3760 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003761 goto exit;
3762 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003763 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003764 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003765 }
3766 do {
3767 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003768 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3769 wcscmp(wFileData.cFileName, L"..") != 0) {
3770 v = PyUnicode_FromWideChar(wFileData.cFileName,
3771 wcslen(wFileData.cFileName));
3772 if (path->narrow && v) {
3773 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3774 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003776 Py_DECREF(list);
3777 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 break;
3779 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003780 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003781 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003782 Py_DECREF(list);
3783 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003784 break;
3785 }
3786 Py_DECREF(v);
3787 }
3788 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003789 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 Py_END_ALLOW_THREADS
3791 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3792 it got to the end of the directory. */
3793 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003794 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003795 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003796 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003797 }
3798 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003799
Larry Hastings9cf065c2012-06-22 16:30:09 -07003800exit:
3801 if (hFindFile != INVALID_HANDLE_VALUE) {
3802 if (FindClose(hFindFile) == FALSE) {
3803 if (list != NULL) {
3804 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003805 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003806 }
3807 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003808 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003809 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003810
Larry Hastings9cf065c2012-06-22 16:30:09 -07003811 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003812} /* end of _listdir_windows_no_opendir */
3813
3814#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3815
3816static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003817_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003818{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003819 PyObject *v;
3820 DIR *dirp = NULL;
3821 struct dirent *ep;
3822 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003823#ifdef HAVE_FDOPENDIR
3824 int fd = -1;
3825#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003826
Victor Stinner8c62be82010-05-06 00:08:46 +00003827 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003828#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003829 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003830 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003831 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003832 if (fd == -1)
3833 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003834
Larry Hastingsfdaea062012-06-25 04:42:23 -07003835 return_str = 1;
3836
Larry Hastings9cf065c2012-06-22 16:30:09 -07003837 Py_BEGIN_ALLOW_THREADS
3838 dirp = fdopendir(fd);
3839 Py_END_ALLOW_THREADS
3840 }
3841 else
3842#endif
3843 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003844 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003845 if (path->narrow) {
3846 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003847 /* only return bytes if they specified a bytes-like object */
3848 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003849 }
3850 else {
3851 name = ".";
3852 return_str = 1;
3853 }
3854
Larry Hastings9cf065c2012-06-22 16:30:09 -07003855 Py_BEGIN_ALLOW_THREADS
3856 dirp = opendir(name);
3857 Py_END_ALLOW_THREADS
3858 }
3859
3860 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003861 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003862#ifdef HAVE_FDOPENDIR
3863 if (fd != -1) {
3864 Py_BEGIN_ALLOW_THREADS
3865 close(fd);
3866 Py_END_ALLOW_THREADS
3867 }
3868#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003869 goto exit;
3870 }
3871 if ((list = PyList_New(0)) == NULL) {
3872 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 }
3874 for (;;) {
3875 errno = 0;
3876 Py_BEGIN_ALLOW_THREADS
3877 ep = readdir(dirp);
3878 Py_END_ALLOW_THREADS
3879 if (ep == NULL) {
3880 if (errno == 0) {
3881 break;
3882 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003883 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003884 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003885 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003886 }
3887 }
3888 if (ep->d_name[0] == '.' &&
3889 (NAMLEN(ep) == 1 ||
3890 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3891 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003892 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003893 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3894 else
3895 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003897 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003898 break;
3899 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003900 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003902 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 break;
3904 }
3905 Py_DECREF(v);
3906 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003907
Larry Hastings9cf065c2012-06-22 16:30:09 -07003908exit:
3909 if (dirp != NULL) {
3910 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003911#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003912 if (fd > -1)
3913 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003914#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003915 closedir(dirp);
3916 Py_END_ALLOW_THREADS
3917 }
3918
Larry Hastings9cf065c2012-06-22 16:30:09 -07003919 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003920} /* end of _posix_listdir */
3921#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003922
Larry Hastings2f936352014-08-05 14:04:04 +10003923
3924/*[clinic input]
3925os.listdir
3926
3927 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3928
3929Return a list containing the names of the files in the directory.
3930
BNMetricsb9427072018-11-02 15:20:19 +00003931path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003932 the filenames returned will also be bytes; in all other circumstances
3933 the filenames returned will be str.
3934If path is None, uses the path='.'.
3935On some platforms, path may also be specified as an open file descriptor;\
3936 the file descriptor must refer to a directory.
3937 If this functionality is unavailable, using it raises NotImplementedError.
3938
3939The list is in arbitrary order. It does not include the special
3940entries '.' and '..' even if they are present in the directory.
3941
3942
3943[clinic start generated code]*/
3944
Larry Hastings2f936352014-08-05 14:04:04 +10003945static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003946os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003947/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003948{
Steve Dower60419a72019-06-24 08:42:54 -07003949 if (PySys_Audit("os.listdir", "O",
3950 path->object ? path->object : Py_None) < 0) {
3951 return NULL;
3952 }
Larry Hastings2f936352014-08-05 14:04:04 +10003953#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3954 return _listdir_windows_no_opendir(path, NULL);
3955#else
3956 return _posix_listdir(path, NULL);
3957#endif
3958}
3959
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003960#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003961/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003962/*[clinic input]
3963os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003964
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003965 path: path_t
3966 /
3967
3968[clinic start generated code]*/
3969
3970static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003971os__getfullpathname_impl(PyObject *module, path_t *path)
3972/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003973{
Victor Stinner3939c322019-06-25 15:02:43 +02003974 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003975
Victor Stinner3939c322019-06-25 15:02:43 +02003976 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
3977 if (_Py_abspath(path->wide, &abspath) < 0) {
3978 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003979 }
Victor Stinner3939c322019-06-25 15:02:43 +02003980 if (abspath == NULL) {
3981 return PyErr_NoMemory();
3982 }
3983
3984 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
3985 PyMem_RawFree(abspath);
3986 if (str == NULL) {
3987 return NULL;
3988 }
3989 if (path->narrow) {
3990 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
3991 }
3992 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10003993}
Brian Curtind40e6f72010-07-08 21:39:08 +00003994
Brian Curtind25aef52011-06-13 15:16:04 -05003995
Larry Hastings2f936352014-08-05 14:04:04 +10003996/*[clinic input]
3997os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003998
Steve Dower23ad6d02018-02-22 10:39:10 -08003999 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004000 /
4001
4002A helper function for samepath on windows.
4003[clinic start generated code]*/
4004
Larry Hastings2f936352014-08-05 14:04:04 +10004005static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004006os__getfinalpathname_impl(PyObject *module, path_t *path)
4007/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004008{
4009 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004010 wchar_t buf[MAXPATHLEN], *target_path = buf;
4011 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004012 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004013 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004014
Steve Dower23ad6d02018-02-22 10:39:10 -08004015 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004016 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004017 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004018 0, /* desired access */
4019 0, /* share mode */
4020 NULL, /* security attributes */
4021 OPEN_EXISTING,
4022 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4023 FILE_FLAG_BACKUP_SEMANTICS,
4024 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004025 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004026
Steve Dower23ad6d02018-02-22 10:39:10 -08004027 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004028 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004029 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004030
4031 /* We have a good handle to the target, use it to determine the
4032 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004033 while (1) {
4034 Py_BEGIN_ALLOW_THREADS
4035 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4036 buf_size, VOLUME_NAME_DOS);
4037 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004038
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004039 if (!result_length) {
4040 result = win32_error_object("GetFinalPathNameByHandleW",
4041 path->object);
4042 goto cleanup;
4043 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004044
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004045 if (result_length < buf_size) {
4046 break;
4047 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004048
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004049 wchar_t *tmp;
4050 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4051 result_length * sizeof(*tmp));
4052 if (!tmp) {
4053 result = PyErr_NoMemory();
4054 goto cleanup;
4055 }
4056
4057 buf_size = result_length;
4058 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004059 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004060
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004061 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004062 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004063 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004064 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004065
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004066cleanup:
4067 if (target_path != buf) {
4068 PyMem_Free(target_path);
4069 }
4070 CloseHandle(hFile);
4071 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004072}
Brian Curtin62857742010-09-06 17:07:27 +00004073
Tim Golden6b528062013-08-01 12:44:00 +01004074
Larry Hastings2f936352014-08-05 14:04:04 +10004075/*[clinic input]
4076os._getvolumepathname
4077
Steve Dower23ad6d02018-02-22 10:39:10 -08004078 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004079
4080A helper function for ismount on Win32.
4081[clinic start generated code]*/
4082
Larry Hastings2f936352014-08-05 14:04:04 +10004083static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004084os__getvolumepathname_impl(PyObject *module, path_t *path)
4085/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004086{
4087 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004088 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004089 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004090 BOOL ret;
4091
Tim Golden6b528062013-08-01 12:44:00 +01004092 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004093 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004094
Victor Stinner850a18e2017-10-24 16:53:32 -07004095 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004096 PyErr_SetString(PyExc_OverflowError, "path too long");
4097 return NULL;
4098 }
4099
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004100 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004101 if (mountpath == NULL)
4102 return PyErr_NoMemory();
4103
4104 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004105 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004106 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004107 Py_END_ALLOW_THREADS
4108
4109 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004110 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004111 goto exit;
4112 }
4113 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004114 if (path->narrow)
4115 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004116
4117exit:
4118 PyMem_Free(mountpath);
4119 return result;
4120}
Tim Golden6b528062013-08-01 12:44:00 +01004121
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004122#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004123
Larry Hastings2f936352014-08-05 14:04:04 +10004124
4125/*[clinic input]
4126os.mkdir
4127
4128 path : path_t
4129
4130 mode: int = 0o777
4131
4132 *
4133
4134 dir_fd : dir_fd(requires='mkdirat') = None
4135
4136# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4137
4138Create a directory.
4139
4140If dir_fd is not None, it should be a file descriptor open to a directory,
4141 and path should be relative; path will then be relative to that directory.
4142dir_fd may not be implemented on your platform.
4143 If it is unavailable, using it will raise a NotImplementedError.
4144
4145The mode argument is ignored on Windows.
4146[clinic start generated code]*/
4147
Larry Hastings2f936352014-08-05 14:04:04 +10004148static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004149os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4150/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004151{
4152 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004153
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004154 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4155 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4156 return NULL;
4157 }
4158
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004159#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004160 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004161 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004162 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004163
Larry Hastings2f936352014-08-05 14:04:04 +10004164 if (!result)
4165 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004166#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004167 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004168#if HAVE_MKDIRAT
4169 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004170 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004171 else
4172#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004173#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004174 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004175#else
Larry Hastings2f936352014-08-05 14:04:04 +10004176 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004177#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004178 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004179 if (result < 0)
4180 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004181#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004182 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004183}
4184
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004185
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004186/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4187#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004188#include <sys/resource.h>
4189#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004190
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004191
4192#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004193/*[clinic input]
4194os.nice
4195
4196 increment: int
4197 /
4198
4199Add increment to the priority of process and return the new priority.
4200[clinic start generated code]*/
4201
Larry Hastings2f936352014-08-05 14:04:04 +10004202static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004203os_nice_impl(PyObject *module, int increment)
4204/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004205{
4206 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004207
Victor Stinner8c62be82010-05-06 00:08:46 +00004208 /* There are two flavours of 'nice': one that returns the new
4209 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004210 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004211 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004212
Victor Stinner8c62be82010-05-06 00:08:46 +00004213 If we are of the nice family that returns the new priority, we
4214 need to clear errno before the call, and check if errno is filled
4215 before calling posix_error() on a returnvalue of -1, because the
4216 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004217
Victor Stinner8c62be82010-05-06 00:08:46 +00004218 errno = 0;
4219 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004220#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004221 if (value == 0)
4222 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004223#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004224 if (value == -1 && errno != 0)
4225 /* either nice() or getpriority() returned an error */
4226 return posix_error();
4227 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004228}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004229#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004230
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004231
4232#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004233/*[clinic input]
4234os.getpriority
4235
4236 which: int
4237 who: int
4238
4239Return program scheduling priority.
4240[clinic start generated code]*/
4241
Larry Hastings2f936352014-08-05 14:04:04 +10004242static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004243os_getpriority_impl(PyObject *module, int which, int who)
4244/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004245{
4246 int retval;
4247
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004248 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004249 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004250 if (errno != 0)
4251 return posix_error();
4252 return PyLong_FromLong((long)retval);
4253}
4254#endif /* HAVE_GETPRIORITY */
4255
4256
4257#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004258/*[clinic input]
4259os.setpriority
4260
4261 which: int
4262 who: int
4263 priority: int
4264
4265Set program scheduling priority.
4266[clinic start generated code]*/
4267
Larry Hastings2f936352014-08-05 14:04:04 +10004268static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004269os_setpriority_impl(PyObject *module, int which, int who, int priority)
4270/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004271{
4272 int retval;
4273
4274 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004275 if (retval == -1)
4276 return posix_error();
4277 Py_RETURN_NONE;
4278}
4279#endif /* HAVE_SETPRIORITY */
4280
4281
Barry Warsaw53699e91996-12-10 23:23:01 +00004282static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004283internal_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 +00004284{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004285 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004286 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004287
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004288#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004289 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004290 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004291#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004292 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004293#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004294
Larry Hastings9cf065c2012-06-22 16:30:09 -07004295 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4296 (dst_dir_fd != DEFAULT_DIR_FD);
4297#ifndef HAVE_RENAMEAT
4298 if (dir_fd_specified) {
4299 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004300 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004301 }
4302#endif
4303
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004304 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4305 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4306 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4307 return NULL;
4308 }
4309
Larry Hastings9cf065c2012-06-22 16:30:09 -07004310#ifdef MS_WINDOWS
4311 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004312 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004313 Py_END_ALLOW_THREADS
4314
Larry Hastings2f936352014-08-05 14:04:04 +10004315 if (!result)
4316 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004317
4318#else
Steve Dowercc16be82016-09-08 10:35:16 -07004319 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4320 PyErr_Format(PyExc_ValueError,
4321 "%s: src and dst must be the same type", function_name);
4322 return NULL;
4323 }
4324
Larry Hastings9cf065c2012-06-22 16:30:09 -07004325 Py_BEGIN_ALLOW_THREADS
4326#ifdef HAVE_RENAMEAT
4327 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004328 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004329 else
4330#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004331 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004332 Py_END_ALLOW_THREADS
4333
Larry Hastings2f936352014-08-05 14:04:04 +10004334 if (result)
4335 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004336#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004337 Py_RETURN_NONE;
4338}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004339
Larry Hastings2f936352014-08-05 14:04:04 +10004340
4341/*[clinic input]
4342os.rename
4343
4344 src : path_t
4345 dst : path_t
4346 *
4347 src_dir_fd : dir_fd = None
4348 dst_dir_fd : dir_fd = None
4349
4350Rename a file or directory.
4351
4352If either src_dir_fd or dst_dir_fd is not None, it should be a file
4353 descriptor open to a directory, and the respective path string (src or dst)
4354 should be relative; the path will then be relative to that directory.
4355src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4356 If they are unavailable, using them will raise a NotImplementedError.
4357[clinic start generated code]*/
4358
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004359static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004360os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004361 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004362/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004363{
Larry Hastings2f936352014-08-05 14:04:04 +10004364 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004365}
4366
Larry Hastings2f936352014-08-05 14:04:04 +10004367
4368/*[clinic input]
4369os.replace = os.rename
4370
4371Rename a file or directory, overwriting the destination.
4372
4373If either src_dir_fd or dst_dir_fd is not None, it should be a file
4374 descriptor open to a directory, and the respective path string (src or dst)
4375 should be relative; the path will then be relative to that directory.
4376src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004377 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004378[clinic start generated code]*/
4379
Larry Hastings2f936352014-08-05 14:04:04 +10004380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004381os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4382 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004383/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004384{
4385 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4386}
4387
4388
4389/*[clinic input]
4390os.rmdir
4391
4392 path: path_t
4393 *
4394 dir_fd: dir_fd(requires='unlinkat') = None
4395
4396Remove a directory.
4397
4398If dir_fd is not None, it should be a file descriptor open to a directory,
4399 and path should be relative; path will then be relative to that directory.
4400dir_fd may not be implemented on your platform.
4401 If it is unavailable, using it will raise a NotImplementedError.
4402[clinic start generated code]*/
4403
Larry Hastings2f936352014-08-05 14:04:04 +10004404static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004405os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4406/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004407{
4408 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004409
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004410 if (PySys_Audit("os.rmdir", "Oi", path->object,
4411 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4412 return NULL;
4413 }
4414
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004415 Py_BEGIN_ALLOW_THREADS
4416#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004417 /* Windows, success=1, UNIX, success=0 */
4418 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004419#else
4420#ifdef HAVE_UNLINKAT
4421 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004422 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004423 else
4424#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004425 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004426#endif
4427 Py_END_ALLOW_THREADS
4428
Larry Hastings2f936352014-08-05 14:04:04 +10004429 if (result)
4430 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004431
Larry Hastings2f936352014-08-05 14:04:04 +10004432 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004433}
4434
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004435
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004436#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004437#ifdef MS_WINDOWS
4438/*[clinic input]
4439os.system -> long
4440
4441 command: Py_UNICODE
4442
4443Execute the command in a subshell.
4444[clinic start generated code]*/
4445
Larry Hastings2f936352014-08-05 14:04:04 +10004446static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004447os_system_impl(PyObject *module, const Py_UNICODE *command)
4448/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004449{
4450 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004451
Steve Dowerfbe3c762019-10-18 00:52:15 -07004452 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004453 return -1;
4454 }
4455
Victor Stinner8c62be82010-05-06 00:08:46 +00004456 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004457 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004458 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004459 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004460 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004461 return result;
4462}
4463#else /* MS_WINDOWS */
4464/*[clinic input]
4465os.system -> long
4466
4467 command: FSConverter
4468
4469Execute the command in a subshell.
4470[clinic start generated code]*/
4471
Larry Hastings2f936352014-08-05 14:04:04 +10004472static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004473os_system_impl(PyObject *module, PyObject *command)
4474/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004475{
4476 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004477 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004478
Steve Dowerfbe3c762019-10-18 00:52:15 -07004479 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004480 return -1;
4481 }
4482
Larry Hastings2f936352014-08-05 14:04:04 +10004483 Py_BEGIN_ALLOW_THREADS
4484 result = system(bytes);
4485 Py_END_ALLOW_THREADS
4486 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004487}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004488#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004489#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004490
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004491
Larry Hastings2f936352014-08-05 14:04:04 +10004492/*[clinic input]
4493os.umask
4494
4495 mask: int
4496 /
4497
4498Set the current numeric umask and return the previous umask.
4499[clinic start generated code]*/
4500
Larry Hastings2f936352014-08-05 14:04:04 +10004501static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004502os_umask_impl(PyObject *module, int mask)
4503/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004504{
4505 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004506 if (i < 0)
4507 return posix_error();
4508 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004509}
4510
Brian Curtind40e6f72010-07-08 21:39:08 +00004511#ifdef MS_WINDOWS
4512
4513/* override the default DeleteFileW behavior so that directory
4514symlinks can be removed with this function, the same as with
4515Unix symlinks */
4516BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4517{
4518 WIN32_FILE_ATTRIBUTE_DATA info;
4519 WIN32_FIND_DATAW find_data;
4520 HANDLE find_data_handle;
4521 int is_directory = 0;
4522 int is_link = 0;
4523
4524 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4525 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004526
Brian Curtind40e6f72010-07-08 21:39:08 +00004527 /* Get WIN32_FIND_DATA structure for the path to determine if
4528 it is a symlink */
4529 if(is_directory &&
4530 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4531 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4532
4533 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004534 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4535 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4536 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4537 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004538 FindClose(find_data_handle);
4539 }
4540 }
4541 }
4542
4543 if (is_directory && is_link)
4544 return RemoveDirectoryW(lpFileName);
4545
4546 return DeleteFileW(lpFileName);
4547}
4548#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004549
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004550
Larry Hastings2f936352014-08-05 14:04:04 +10004551/*[clinic input]
4552os.unlink
4553
4554 path: path_t
4555 *
4556 dir_fd: dir_fd(requires='unlinkat')=None
4557
4558Remove a file (same as remove()).
4559
4560If dir_fd is not None, it should be a file descriptor open to a directory,
4561 and path should be relative; path will then be relative to that directory.
4562dir_fd may not be implemented on your platform.
4563 If it is unavailable, using it will raise a NotImplementedError.
4564
4565[clinic start generated code]*/
4566
Larry Hastings2f936352014-08-05 14:04:04 +10004567static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004568os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4569/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004570{
4571 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004573 if (PySys_Audit("os.remove", "Oi", path->object,
4574 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4575 return NULL;
4576 }
4577
Larry Hastings9cf065c2012-06-22 16:30:09 -07004578 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004579 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004580#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004581 /* Windows, success=1, UNIX, success=0 */
4582 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004583#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584#ifdef HAVE_UNLINKAT
4585 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004586 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004587 else
4588#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004589 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004591 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592 Py_END_ALLOW_THREADS
4593
Larry Hastings2f936352014-08-05 14:04:04 +10004594 if (result)
4595 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004596
Larry Hastings2f936352014-08-05 14:04:04 +10004597 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004598}
4599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004600
Larry Hastings2f936352014-08-05 14:04:04 +10004601/*[clinic input]
4602os.remove = os.unlink
4603
4604Remove a file (same as unlink()).
4605
4606If dir_fd is not None, it should be a file descriptor open to a directory,
4607 and path should be relative; path will then be relative to that directory.
4608dir_fd may not be implemented on your platform.
4609 If it is unavailable, using it will raise a NotImplementedError.
4610[clinic start generated code]*/
4611
Larry Hastings2f936352014-08-05 14:04:04 +10004612static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004613os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4614/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004615{
4616 return os_unlink_impl(module, path, dir_fd);
4617}
4618
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004619
Larry Hastings605a62d2012-06-24 04:33:36 -07004620static PyStructSequence_Field uname_result_fields[] = {
4621 {"sysname", "operating system name"},
4622 {"nodename", "name of machine on network (implementation-defined)"},
4623 {"release", "operating system release"},
4624 {"version", "operating system version"},
4625 {"machine", "hardware identifier"},
4626 {NULL}
4627};
4628
4629PyDoc_STRVAR(uname_result__doc__,
4630"uname_result: Result from os.uname().\n\n\
4631This object may be accessed either as a tuple of\n\
4632 (sysname, nodename, release, version, machine),\n\
4633or via the attributes sysname, nodename, release, version, and machine.\n\
4634\n\
4635See os.uname for more information.");
4636
4637static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08004638 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07004639 uname_result__doc__, /* doc */
4640 uname_result_fields,
4641 5
4642};
4643
Larry Hastings605a62d2012-06-24 04:33:36 -07004644#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004645/*[clinic input]
4646os.uname
4647
4648Return an object identifying the current operating system.
4649
4650The object behaves like a named tuple with the following fields:
4651 (sysname, nodename, release, version, machine)
4652
4653[clinic start generated code]*/
4654
Larry Hastings2f936352014-08-05 14:04:04 +10004655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004656os_uname_impl(PyObject *module)
4657/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004658{
Victor Stinner8c62be82010-05-06 00:08:46 +00004659 struct utsname u;
4660 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004661 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004662
Victor Stinner8c62be82010-05-06 00:08:46 +00004663 Py_BEGIN_ALLOW_THREADS
4664 res = uname(&u);
4665 Py_END_ALLOW_THREADS
4666 if (res < 0)
4667 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004668
Hai Shif707d942020-03-16 21:15:01 +08004669 PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08004670 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004671 if (value == NULL)
4672 return NULL;
4673
4674#define SET(i, field) \
4675 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004676 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004677 if (!o) { \
4678 Py_DECREF(value); \
4679 return NULL; \
4680 } \
4681 PyStructSequence_SET_ITEM(value, i, o); \
4682 } \
4683
4684 SET(0, u.sysname);
4685 SET(1, u.nodename);
4686 SET(2, u.release);
4687 SET(3, u.version);
4688 SET(4, u.machine);
4689
4690#undef SET
4691
4692 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004693}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004694#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004695
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004696
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697
4698typedef struct {
4699 int now;
4700 time_t atime_s;
4701 long atime_ns;
4702 time_t mtime_s;
4703 long mtime_ns;
4704} utime_t;
4705
4706/*
Victor Stinner484df002014-10-09 13:52:31 +02004707 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 * they also intentionally leak the declaration of a pointer named "time"
4709 */
4710#define UTIME_TO_TIMESPEC \
4711 struct timespec ts[2]; \
4712 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004713 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004714 time = NULL; \
4715 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004716 ts[0].tv_sec = ut->atime_s; \
4717 ts[0].tv_nsec = ut->atime_ns; \
4718 ts[1].tv_sec = ut->mtime_s; \
4719 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720 time = ts; \
4721 } \
4722
4723#define UTIME_TO_TIMEVAL \
4724 struct timeval tv[2]; \
4725 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004726 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 time = NULL; \
4728 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004729 tv[0].tv_sec = ut->atime_s; \
4730 tv[0].tv_usec = ut->atime_ns / 1000; \
4731 tv[1].tv_sec = ut->mtime_s; \
4732 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004733 time = tv; \
4734 } \
4735
4736#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004737 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004739 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004740 time = NULL; \
4741 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004742 u.actime = ut->atime_s; \
4743 u.modtime = ut->mtime_s; \
4744 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 }
4746
4747#define UTIME_TO_TIME_T \
4748 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004749 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004750 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751 time = NULL; \
4752 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004753 timet[0] = ut->atime_s; \
4754 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004755 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756 } \
4757
4758
Victor Stinner528a9ab2015-09-03 21:30:26 +02004759#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004760
4761static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004762utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763{
4764#ifdef HAVE_UTIMENSAT
4765 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4766 UTIME_TO_TIMESPEC;
4767 return utimensat(dir_fd, path, time, flags);
4768#elif defined(HAVE_FUTIMESAT)
4769 UTIME_TO_TIMEVAL;
4770 /*
4771 * follow_symlinks will never be false here;
4772 * we only allow !follow_symlinks and dir_fd together
4773 * if we have utimensat()
4774 */
4775 assert(follow_symlinks);
4776 return futimesat(dir_fd, path, time);
4777#endif
4778}
4779
Larry Hastings2f936352014-08-05 14:04:04 +10004780 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4781#else
4782 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004783#endif
4784
Victor Stinner528a9ab2015-09-03 21:30:26 +02004785#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004786
4787static int
Victor Stinner484df002014-10-09 13:52:31 +02004788utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004789{
4790#ifdef HAVE_FUTIMENS
4791 UTIME_TO_TIMESPEC;
4792 return futimens(fd, time);
4793#else
4794 UTIME_TO_TIMEVAL;
4795 return futimes(fd, time);
4796#endif
4797}
4798
Larry Hastings2f936352014-08-05 14:04:04 +10004799 #define PATH_UTIME_HAVE_FD 1
4800#else
4801 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004802#endif
4803
Victor Stinner5ebae872015-09-22 01:29:33 +02004804#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4805# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4806#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004807
Victor Stinner4552ced2015-09-21 22:37:15 +02004808#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809
4810static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004811utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004812{
4813#ifdef HAVE_UTIMENSAT
4814 UTIME_TO_TIMESPEC;
4815 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4816#else
4817 UTIME_TO_TIMEVAL;
4818 return lutimes(path, time);
4819#endif
4820}
4821
4822#endif
4823
4824#ifndef MS_WINDOWS
4825
4826static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004827utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004828{
4829#ifdef HAVE_UTIMENSAT
4830 UTIME_TO_TIMESPEC;
4831 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4832#elif defined(HAVE_UTIMES)
4833 UTIME_TO_TIMEVAL;
4834 return utimes(path, time);
4835#elif defined(HAVE_UTIME_H)
4836 UTIME_TO_UTIMBUF;
4837 return utime(path, time);
4838#else
4839 UTIME_TO_TIME_T;
4840 return utime(path, time);
4841#endif
4842}
4843
4844#endif
4845
Larry Hastings76ad59b2012-05-03 00:30:07 -07004846static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02004847split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004848{
4849 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004850 PyObject *divmod;
Victor Stinner1c2fa782020-05-10 11:05:29 +02004851 divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07004852 if (!divmod)
4853 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004854 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4855 PyErr_Format(PyExc_TypeError,
4856 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08004857 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004858 goto exit;
4859 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004860 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4861 if ((*s == -1) && PyErr_Occurred())
4862 goto exit;
4863 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004864 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004865 goto exit;
4866
4867 result = 1;
4868exit:
4869 Py_XDECREF(divmod);
4870 return result;
4871}
4872
Larry Hastings2f936352014-08-05 14:04:04 +10004873
4874/*[clinic input]
4875os.utime
4876
4877 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004878 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10004879 *
4880 ns: object = NULL
4881 dir_fd: dir_fd(requires='futimensat') = None
4882 follow_symlinks: bool=True
4883
Martin Panter0ff89092015-09-09 01:56:53 +00004884# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004885
4886Set the access and modified time of path.
4887
4888path may always be specified as a string.
4889On some platforms, path may also be specified as an open file descriptor.
4890 If this functionality is unavailable, using it raises an exception.
4891
4892If times is not None, it must be a tuple (atime, mtime);
4893 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004894If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004895 atime_ns and mtime_ns should be expressed as integer nanoseconds
4896 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004897If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004898Specifying tuples for both times and ns is an error.
4899
4900If dir_fd is not None, it should be a file descriptor open to a directory,
4901 and path should be relative; path will then be relative to that directory.
4902If follow_symlinks is False, and the last element of the path is a symbolic
4903 link, utime will modify the symbolic link itself instead of the file the
4904 link points to.
4905It is an error to use dir_fd or follow_symlinks when specifying path
4906 as an open file descriptor.
4907dir_fd and follow_symlinks may not be available on your platform.
4908 If they are unavailable, using them will raise a NotImplementedError.
4909
4910[clinic start generated code]*/
4911
Larry Hastings2f936352014-08-05 14:04:04 +10004912static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004913os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4914 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004915/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004916{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004917#ifdef MS_WINDOWS
4918 HANDLE hFile;
4919 FILETIME atime, mtime;
4920#else
4921 int result;
4922#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004923
Larry Hastings2f936352014-08-05 14:04:04 +10004924 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004925
Christian Heimesb3c87242013-08-01 00:08:16 +02004926 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004927
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004928 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004929 PyErr_SetString(PyExc_ValueError,
4930 "utime: you may specify either 'times'"
4931 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004932 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004933 }
4934
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004935 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004936 time_t a_sec, m_sec;
4937 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004938 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004939 PyErr_SetString(PyExc_TypeError,
4940 "utime: 'times' must be either"
4941 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004942 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004943 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004944 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004945 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004946 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004947 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004948 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004949 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004950 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004951 utime.atime_s = a_sec;
4952 utime.atime_ns = a_nsec;
4953 utime.mtime_s = m_sec;
4954 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004955 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004956 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004957 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004958 PyErr_SetString(PyExc_TypeError,
4959 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004960 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004961 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004962 utime.now = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02004963 if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004964 &utime.atime_s, &utime.atime_ns) ||
Victor Stinner1c2fa782020-05-10 11:05:29 +02004965 !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004966 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004967 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004968 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004969 }
4970 else {
4971 /* times and ns are both None/unspecified. use "now". */
4972 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004973 }
4974
Victor Stinner4552ced2015-09-21 22:37:15 +02004975#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004976 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004977 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004978#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004979
Larry Hastings2f936352014-08-05 14:04:04 +10004980 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4981 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4982 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004983 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004984
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985#if !defined(HAVE_UTIMENSAT)
4986 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004987 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004988 "utime: cannot use dir_fd and follow_symlinks "
4989 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004990 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004991 }
4992#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004993
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004994 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
4995 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4996 return NULL;
4997 }
4998
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004999#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005000 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005001 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5002 NULL, OPEN_EXISTING,
5003 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005004 Py_END_ALLOW_THREADS
5005 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005006 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005007 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005008 }
5009
Larry Hastings9cf065c2012-06-22 16:30:09 -07005010 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005011 GetSystemTimeAsFileTime(&mtime);
5012 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005013 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005014 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005015 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5016 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 }
5018 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5019 /* Avoid putting the file name into the error here,
5020 as that may confuse the user into believing that
5021 something is wrong with the file, when it also
5022 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005023 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005024 CloseHandle(hFile);
5025 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005026 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005027 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005028#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005029 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005030
Victor Stinner4552ced2015-09-21 22:37:15 +02005031#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005032 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005033 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005034 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005035#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005036
Victor Stinner528a9ab2015-09-03 21:30:26 +02005037#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005038 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10005039 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005040 else
5041#endif
5042
Victor Stinner528a9ab2015-09-03 21:30:26 +02005043#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005044 if (path->fd != -1)
5045 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005046 else
5047#endif
5048
Larry Hastings2f936352014-08-05 14:04:04 +10005049 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005050
5051 Py_END_ALLOW_THREADS
5052
5053 if (result < 0) {
5054 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005055 posix_error();
5056 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005057 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005058
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005059#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005060
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005061 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005062}
5063
Guido van Rossum3b066191991-06-04 19:40:25 +00005064/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005065
Larry Hastings2f936352014-08-05 14:04:04 +10005066
5067/*[clinic input]
5068os._exit
5069
5070 status: int
5071
5072Exit to the system with specified status, without normal exit processing.
5073[clinic start generated code]*/
5074
Larry Hastings2f936352014-08-05 14:04:04 +10005075static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005076os__exit_impl(PyObject *module, int status)
5077/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005078{
5079 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005080 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005081}
5082
Steve Dowercc16be82016-09-08 10:35:16 -07005083#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5084#define EXECV_CHAR wchar_t
5085#else
5086#define EXECV_CHAR char
5087#endif
5088
pxinwrf2d7ac72019-05-21 18:46:37 +08005089#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005090static void
Steve Dowercc16be82016-09-08 10:35:16 -07005091free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005092{
Victor Stinner8c62be82010-05-06 00:08:46 +00005093 Py_ssize_t i;
5094 for (i = 0; i < count; i++)
5095 PyMem_Free(array[i]);
5096 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005097}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005098
Berker Peksag81816462016-09-15 20:19:47 +03005099static int
5100fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005101{
Victor Stinner8c62be82010-05-06 00:08:46 +00005102 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005103 PyObject *ub;
5104 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005105#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005106 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005107 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005108 *out = PyUnicode_AsWideCharString(ub, &size);
5109 if (*out)
5110 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005111#else
Berker Peksag81816462016-09-15 20:19:47 +03005112 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005113 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005114 size = PyBytes_GET_SIZE(ub);
5115 *out = PyMem_Malloc(size + 1);
5116 if (*out) {
5117 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5118 result = 1;
5119 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005120 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005121#endif
Berker Peksag81816462016-09-15 20:19:47 +03005122 Py_DECREF(ub);
5123 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005124}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005125#endif
5126
pxinwrf2d7ac72019-05-21 18:46:37 +08005127#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005128static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005129parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5130{
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 Py_ssize_t i, pos, envc;
5132 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005133 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005134 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005135
Victor Stinner8c62be82010-05-06 00:08:46 +00005136 i = PyMapping_Size(env);
5137 if (i < 0)
5138 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005139 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 if (envlist == NULL) {
5141 PyErr_NoMemory();
5142 return NULL;
5143 }
5144 envc = 0;
5145 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005146 if (!keys)
5147 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005149 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005150 goto error;
5151 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5152 PyErr_Format(PyExc_TypeError,
5153 "env.keys() or env.values() is not a list");
5154 goto error;
5155 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005156
Victor Stinner8c62be82010-05-06 00:08:46 +00005157 for (pos = 0; pos < i; pos++) {
5158 key = PyList_GetItem(keys, pos);
5159 val = PyList_GetItem(vals, pos);
5160 if (!key || !val)
5161 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005162
Berker Peksag81816462016-09-15 20:19:47 +03005163#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5164 if (!PyUnicode_FSDecoder(key, &key2))
5165 goto error;
5166 if (!PyUnicode_FSDecoder(val, &val2)) {
5167 Py_DECREF(key2);
5168 goto error;
5169 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005170 /* Search from index 1 because on Windows starting '=' is allowed for
5171 defining hidden environment variables. */
5172 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5173 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5174 {
5175 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005176 Py_DECREF(key2);
5177 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005178 goto error;
5179 }
Berker Peksag81816462016-09-15 20:19:47 +03005180 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5181#else
5182 if (!PyUnicode_FSConverter(key, &key2))
5183 goto error;
5184 if (!PyUnicode_FSConverter(val, &val2)) {
5185 Py_DECREF(key2);
5186 goto error;
5187 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005188 if (PyBytes_GET_SIZE(key2) == 0 ||
5189 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5190 {
5191 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005192 Py_DECREF(key2);
5193 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005194 goto error;
5195 }
Berker Peksag81816462016-09-15 20:19:47 +03005196 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5197 PyBytes_AS_STRING(val2));
5198#endif
5199 Py_DECREF(key2);
5200 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005201 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005202 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005203
5204 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5205 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005206 goto error;
5207 }
Berker Peksag81816462016-09-15 20:19:47 +03005208
Steve Dowercc16be82016-09-08 10:35:16 -07005209 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005210 }
5211 Py_DECREF(vals);
5212 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005213
Victor Stinner8c62be82010-05-06 00:08:46 +00005214 envlist[envc] = 0;
5215 *envc_ptr = envc;
5216 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005217
5218error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005219 Py_XDECREF(keys);
5220 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005221 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005222 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005223}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005224
Steve Dowercc16be82016-09-08 10:35:16 -07005225static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005226parse_arglist(PyObject* argv, Py_ssize_t *argc)
5227{
5228 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005229 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005230 if (argvlist == NULL) {
5231 PyErr_NoMemory();
5232 return NULL;
5233 }
5234 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005235 PyObject* item = PySequence_ITEM(argv, i);
5236 if (item == NULL)
5237 goto fail;
5238 if (!fsconvert_strdup(item, &argvlist[i])) {
5239 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005240 goto fail;
5241 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005242 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005243 }
5244 argvlist[*argc] = NULL;
5245 return argvlist;
5246fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005247 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005248 free_string_array(argvlist, *argc);
5249 return NULL;
5250}
Steve Dowercc16be82016-09-08 10:35:16 -07005251
Ross Lagerwall7807c352011-03-17 20:20:30 +02005252#endif
5253
Larry Hastings2f936352014-08-05 14:04:04 +10005254
Ross Lagerwall7807c352011-03-17 20:20:30 +02005255#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005256/*[clinic input]
5257os.execv
5258
Steve Dowercc16be82016-09-08 10:35:16 -07005259 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005260 Path of executable file.
5261 argv: object
5262 Tuple or list of strings.
5263 /
5264
5265Execute an executable path with arguments, replacing current process.
5266[clinic start generated code]*/
5267
Larry Hastings2f936352014-08-05 14:04:04 +10005268static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005269os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5270/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005271{
Steve Dowercc16be82016-09-08 10:35:16 -07005272 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005273 Py_ssize_t argc;
5274
5275 /* execv has two arguments: (path, argv), where
5276 argv is a list or tuple of strings. */
5277
Ross Lagerwall7807c352011-03-17 20:20:30 +02005278 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5279 PyErr_SetString(PyExc_TypeError,
5280 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005281 return NULL;
5282 }
5283 argc = PySequence_Size(argv);
5284 if (argc < 1) {
5285 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005286 return NULL;
5287 }
5288
5289 argvlist = parse_arglist(argv, &argc);
5290 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005291 return NULL;
5292 }
Steve Dowerbce26262016-11-19 19:17:26 -08005293 if (!argvlist[0][0]) {
5294 PyErr_SetString(PyExc_ValueError,
5295 "execv() arg 2 first element cannot be empty");
5296 free_string_array(argvlist, argc);
5297 return NULL;
5298 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005299
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005300 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005301 free_string_array(argvlist, argc);
5302 return NULL;
5303 }
5304
Steve Dowerbce26262016-11-19 19:17:26 -08005305 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005306#ifdef HAVE_WEXECV
5307 _wexecv(path->wide, argvlist);
5308#else
5309 execv(path->narrow, argvlist);
5310#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005311 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005312
5313 /* If we get here it's definitely an error */
5314
5315 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005316 return posix_error();
5317}
5318
Larry Hastings2f936352014-08-05 14:04:04 +10005319
5320/*[clinic input]
5321os.execve
5322
5323 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5324 Path of executable file.
5325 argv: object
5326 Tuple or list of strings.
5327 env: object
5328 Dictionary of strings mapping to strings.
5329
5330Execute an executable path with arguments, replacing current process.
5331[clinic start generated code]*/
5332
Larry Hastings2f936352014-08-05 14:04:04 +10005333static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005334os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5335/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005336{
Steve Dowercc16be82016-09-08 10:35:16 -07005337 EXECV_CHAR **argvlist = NULL;
5338 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005339 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005340
Victor Stinner8c62be82010-05-06 00:08:46 +00005341 /* execve has three arguments: (path, argv, env), where
5342 argv is a list or tuple of strings and env is a dictionary
5343 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005344
Ross Lagerwall7807c352011-03-17 20:20:30 +02005345 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005346 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005347 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005348 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005349 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005350 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005351 if (argc < 1) {
5352 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5353 return NULL;
5354 }
5355
Victor Stinner8c62be82010-05-06 00:08:46 +00005356 if (!PyMapping_Check(env)) {
5357 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005358 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005359 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005360 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005361
Ross Lagerwall7807c352011-03-17 20:20:30 +02005362 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005363 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005364 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005365 }
Steve Dowerbce26262016-11-19 19:17:26 -08005366 if (!argvlist[0][0]) {
5367 PyErr_SetString(PyExc_ValueError,
5368 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005369 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005370 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005371
Victor Stinner8c62be82010-05-06 00:08:46 +00005372 envlist = parse_envlist(env, &envc);
5373 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005374 goto fail_0;
5375
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005376 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005377 goto fail_1;
5378 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005379
Steve Dowerbce26262016-11-19 19:17:26 -08005380 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005381#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005382 if (path->fd > -1)
5383 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005384 else
5385#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005386#ifdef HAVE_WEXECV
5387 _wexecve(path->wide, argvlist, envlist);
5388#else
Larry Hastings2f936352014-08-05 14:04:04 +10005389 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005390#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005391 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005392
5393 /* If we get here it's definitely an error */
5394
Alexey Izbyshev83460312018-10-20 03:28:22 +03005395 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005396 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005397 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005398 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005399 if (argvlist)
5400 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005401 return NULL;
5402}
Steve Dowercc16be82016-09-08 10:35:16 -07005403
Larry Hastings9cf065c2012-06-22 16:30:09 -07005404#endif /* HAVE_EXECV */
5405
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005406#ifdef HAVE_POSIX_SPAWN
5407
5408enum posix_spawn_file_actions_identifier {
5409 POSIX_SPAWN_OPEN,
5410 POSIX_SPAWN_CLOSE,
5411 POSIX_SPAWN_DUP2
5412};
5413
William Orr81574b82018-10-01 22:19:56 -07005414#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005415static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005416convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005417#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005418
5419static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005420parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005421 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005422 PyObject *setsigdef, PyObject *scheduler,
5423 posix_spawnattr_t *attrp)
5424{
5425 long all_flags = 0;
5426
5427 errno = posix_spawnattr_init(attrp);
5428 if (errno) {
5429 posix_error();
5430 return -1;
5431 }
5432
5433 if (setpgroup) {
5434 pid_t pgid = PyLong_AsPid(setpgroup);
5435 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5436 goto fail;
5437 }
5438 errno = posix_spawnattr_setpgroup(attrp, pgid);
5439 if (errno) {
5440 posix_error();
5441 goto fail;
5442 }
5443 all_flags |= POSIX_SPAWN_SETPGROUP;
5444 }
5445
5446 if (resetids) {
5447 all_flags |= POSIX_SPAWN_RESETIDS;
5448 }
5449
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005450 if (setsid) {
5451#ifdef POSIX_SPAWN_SETSID
5452 all_flags |= POSIX_SPAWN_SETSID;
5453#elif defined(POSIX_SPAWN_SETSID_NP)
5454 all_flags |= POSIX_SPAWN_SETSID_NP;
5455#else
5456 argument_unavailable_error(func_name, "setsid");
5457 return -1;
5458#endif
5459 }
5460
Pablo Galindo254a4662018-09-07 16:44:24 +01005461 if (setsigmask) {
5462 sigset_t set;
5463 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5464 goto fail;
5465 }
5466 errno = posix_spawnattr_setsigmask(attrp, &set);
5467 if (errno) {
5468 posix_error();
5469 goto fail;
5470 }
5471 all_flags |= POSIX_SPAWN_SETSIGMASK;
5472 }
5473
5474 if (setsigdef) {
5475 sigset_t set;
5476 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5477 goto fail;
5478 }
5479 errno = posix_spawnattr_setsigdefault(attrp, &set);
5480 if (errno) {
5481 posix_error();
5482 goto fail;
5483 }
5484 all_flags |= POSIX_SPAWN_SETSIGDEF;
5485 }
5486
5487 if (scheduler) {
5488#ifdef POSIX_SPAWN_SETSCHEDULER
5489 PyObject *py_schedpolicy;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005490 PyObject *schedparam_obj;
Pablo Galindo254a4662018-09-07 16:44:24 +01005491 struct sched_param schedparam;
5492
Victor Stinner1c2fa782020-05-10 11:05:29 +02005493 if (!PyArg_ParseTuple(scheduler, "OO"
Pablo Galindo254a4662018-09-07 16:44:24 +01005494 ";A scheduler tuple must have two elements",
Victor Stinner1c2fa782020-05-10 11:05:29 +02005495 &py_schedpolicy, &schedparam_obj)) {
5496 goto fail;
5497 }
5498 if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005499 goto fail;
5500 }
5501 if (py_schedpolicy != Py_None) {
5502 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5503
5504 if (schedpolicy == -1 && PyErr_Occurred()) {
5505 goto fail;
5506 }
5507 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5508 if (errno) {
5509 posix_error();
5510 goto fail;
5511 }
5512 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5513 }
5514 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5515 if (errno) {
5516 posix_error();
5517 goto fail;
5518 }
5519 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5520#else
5521 PyErr_SetString(PyExc_NotImplementedError,
5522 "The scheduler option is not supported in this system.");
5523 goto fail;
5524#endif
5525 }
5526
5527 errno = posix_spawnattr_setflags(attrp, all_flags);
5528 if (errno) {
5529 posix_error();
5530 goto fail;
5531 }
5532
5533 return 0;
5534
5535fail:
5536 (void)posix_spawnattr_destroy(attrp);
5537 return -1;
5538}
5539
5540static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005541parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005542 posix_spawn_file_actions_t *file_actionsp,
5543 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005544{
5545 PyObject *seq;
5546 PyObject *file_action = NULL;
5547 PyObject *tag_obj;
5548
5549 seq = PySequence_Fast(file_actions,
5550 "file_actions must be a sequence or None");
5551 if (seq == NULL) {
5552 return -1;
5553 }
5554
5555 errno = posix_spawn_file_actions_init(file_actionsp);
5556 if (errno) {
5557 posix_error();
5558 Py_DECREF(seq);
5559 return -1;
5560 }
5561
Zackery Spytzd52a83a2019-06-26 14:54:20 -06005562 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03005563 file_action = PySequence_Fast_GET_ITEM(seq, i);
5564 Py_INCREF(file_action);
5565 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5566 PyErr_SetString(PyExc_TypeError,
5567 "Each file_actions element must be a non-empty tuple");
5568 goto fail;
5569 }
5570 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5571 if (tag == -1 && PyErr_Occurred()) {
5572 goto fail;
5573 }
5574
5575 /* Populate the file_actions object */
5576 switch (tag) {
5577 case POSIX_SPAWN_OPEN: {
5578 int fd, oflag;
5579 PyObject *path;
5580 unsigned long mode;
5581 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5582 ";A open file_action tuple must have 5 elements",
5583 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5584 &oflag, &mode))
5585 {
5586 goto fail;
5587 }
Pablo Galindocb970732018-06-19 09:19:50 +01005588 if (PyList_Append(temp_buffer, path)) {
5589 Py_DECREF(path);
5590 goto fail;
5591 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005592 errno = posix_spawn_file_actions_addopen(file_actionsp,
5593 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005594 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005595 if (errno) {
5596 posix_error();
5597 goto fail;
5598 }
5599 break;
5600 }
5601 case POSIX_SPAWN_CLOSE: {
5602 int fd;
5603 if (!PyArg_ParseTuple(file_action, "Oi"
5604 ";A close file_action tuple must have 2 elements",
5605 &tag_obj, &fd))
5606 {
5607 goto fail;
5608 }
5609 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5610 if (errno) {
5611 posix_error();
5612 goto fail;
5613 }
5614 break;
5615 }
5616 case POSIX_SPAWN_DUP2: {
5617 int fd1, fd2;
5618 if (!PyArg_ParseTuple(file_action, "Oii"
5619 ";A dup2 file_action tuple must have 3 elements",
5620 &tag_obj, &fd1, &fd2))
5621 {
5622 goto fail;
5623 }
5624 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5625 fd1, fd2);
5626 if (errno) {
5627 posix_error();
5628 goto fail;
5629 }
5630 break;
5631 }
5632 default: {
5633 PyErr_SetString(PyExc_TypeError,
5634 "Unknown file_actions identifier");
5635 goto fail;
5636 }
5637 }
5638 Py_DECREF(file_action);
5639 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005640
Serhiy Storchakaef347532018-05-01 16:45:04 +03005641 Py_DECREF(seq);
5642 return 0;
5643
5644fail:
5645 Py_DECREF(seq);
5646 Py_DECREF(file_action);
5647 (void)posix_spawn_file_actions_destroy(file_actionsp);
5648 return -1;
5649}
5650
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005651
5652static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005653py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5654 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005655 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005656 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005657{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005658 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005659 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005660 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005661 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005662 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005663 posix_spawnattr_t attr;
5664 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005665 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005666 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005667 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005668 pid_t pid;
5669 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005670
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005671 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005672 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005673 like posix.environ. */
5674
Serhiy Storchakaef347532018-05-01 16:45:04 +03005675 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005676 PyErr_Format(PyExc_TypeError,
5677 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005678 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005679 }
5680 argc = PySequence_Size(argv);
5681 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005682 PyErr_Format(PyExc_ValueError,
5683 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005684 return NULL;
5685 }
5686
5687 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005688 PyErr_Format(PyExc_TypeError,
5689 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005690 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005691 }
5692
5693 argvlist = parse_arglist(argv, &argc);
5694 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005695 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005696 }
5697 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005698 PyErr_Format(PyExc_ValueError,
5699 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005700 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005701 }
5702
5703 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005704 if (envlist == NULL) {
5705 goto exit;
5706 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005707
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005708 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005709 /* There is a bug in old versions of glibc that makes some of the
5710 * helper functions for manipulating file actions not copy the provided
5711 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5712 * copy the value of path for some old versions of glibc (<2.20).
5713 * The use of temp_buffer here is a workaround that keeps the
5714 * python objects that own the buffers alive until posix_spawn gets called.
5715 * Check https://bugs.python.org/issue33630 and
5716 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5717 temp_buffer = PyList_New(0);
5718 if (!temp_buffer) {
5719 goto exit;
5720 }
5721 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005722 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005723 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005724 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005725 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005726
Victor Stinner1c2fa782020-05-10 11:05:29 +02005727 if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005728 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005729 goto exit;
5730 }
5731 attrp = &attr;
5732
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005733 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005734 goto exit;
5735 }
5736
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005737 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005738#ifdef HAVE_POSIX_SPAWNP
5739 if (use_posix_spawnp) {
5740 err_code = posix_spawnp(&pid, path->narrow,
5741 file_actionsp, attrp, argvlist, envlist);
5742 }
5743 else
5744#endif /* HAVE_POSIX_SPAWNP */
5745 {
5746 err_code = posix_spawn(&pid, path->narrow,
5747 file_actionsp, attrp, argvlist, envlist);
5748 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005749 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005750
Serhiy Storchakaef347532018-05-01 16:45:04 +03005751 if (err_code) {
5752 errno = err_code;
5753 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005754 goto exit;
5755 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005756#ifdef _Py_MEMORY_SANITIZER
5757 __msan_unpoison(&pid, sizeof(pid));
5758#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005759 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005760
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005761exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005762 if (file_actionsp) {
5763 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005764 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005765 if (attrp) {
5766 (void)posix_spawnattr_destroy(attrp);
5767 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005768 if (envlist) {
5769 free_string_array(envlist, envc);
5770 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005771 if (argvlist) {
5772 free_string_array(argvlist, argc);
5773 }
Pablo Galindocb970732018-06-19 09:19:50 +01005774 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005775 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005776}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005777
5778
5779/*[clinic input]
5780
5781os.posix_spawn
5782 path: path_t
5783 Path of executable file.
5784 argv: object
5785 Tuple or list of strings.
5786 env: object
5787 Dictionary of strings mapping to strings.
5788 /
5789 *
5790 file_actions: object(c_default='NULL') = ()
5791 A sequence of file action tuples.
5792 setpgroup: object = NULL
5793 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5794 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005795 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5796 setsid: bool(accept={int}) = False
5797 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005798 setsigmask: object(c_default='NULL') = ()
5799 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5800 setsigdef: object(c_default='NULL') = ()
5801 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5802 scheduler: object = NULL
5803 A tuple with the scheduler policy (optional) and parameters.
5804
5805Execute the program specified by path in a new process.
5806[clinic start generated code]*/
5807
5808static PyObject *
5809os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5810 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005811 PyObject *setpgroup, int resetids, int setsid,
5812 PyObject *setsigmask, PyObject *setsigdef,
5813 PyObject *scheduler)
5814/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005815{
5816 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005817 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005818 scheduler);
5819}
5820 #endif /* HAVE_POSIX_SPAWN */
5821
5822
5823
5824#ifdef HAVE_POSIX_SPAWNP
5825/*[clinic input]
5826
5827os.posix_spawnp
5828 path: path_t
5829 Path of executable file.
5830 argv: object
5831 Tuple or list of strings.
5832 env: object
5833 Dictionary of strings mapping to strings.
5834 /
5835 *
5836 file_actions: object(c_default='NULL') = ()
5837 A sequence of file action tuples.
5838 setpgroup: object = NULL
5839 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5840 resetids: bool(accept={int}) = False
5841 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005842 setsid: bool(accept={int}) = False
5843 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005844 setsigmask: object(c_default='NULL') = ()
5845 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5846 setsigdef: object(c_default='NULL') = ()
5847 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5848 scheduler: object = NULL
5849 A tuple with the scheduler policy (optional) and parameters.
5850
5851Execute the program specified by path in a new process.
5852[clinic start generated code]*/
5853
5854static PyObject *
5855os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5856 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005857 PyObject *setpgroup, int resetids, int setsid,
5858 PyObject *setsigmask, PyObject *setsigdef,
5859 PyObject *scheduler)
5860/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005861{
5862 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005863 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005864 scheduler);
5865}
5866#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005867
pxinwrf2d7ac72019-05-21 18:46:37 +08005868#ifdef HAVE_RTPSPAWN
5869static intptr_t
5870_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5871 const char *envp[])
5872{
5873 RTP_ID rtpid;
5874 int status;
5875 pid_t res;
5876 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005877
pxinwrf2d7ac72019-05-21 18:46:37 +08005878 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5879 uStackSize=0 cannot be used, the default stack size is too small for
5880 Python. */
5881 if (envp) {
5882 rtpid = rtpSpawn(rtpFileName, argv, envp,
5883 100, 0x1000000, 0, VX_FP_TASK);
5884 }
5885 else {
5886 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5887 100, 0x1000000, 0, VX_FP_TASK);
5888 }
5889 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5890 do {
5891 res = waitpid((pid_t)rtpid, &status, 0);
5892 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5893
5894 if (res < 0)
5895 return RTP_ID_ERROR;
5896 return ((intptr_t)status);
5897 }
5898 return ((intptr_t)rtpid);
5899}
5900#endif
5901
5902#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005903/*[clinic input]
5904os.spawnv
5905
5906 mode: int
5907 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005908 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005909 Path of executable file.
5910 argv: object
5911 Tuple or list of strings.
5912 /
5913
5914Execute the program specified by path in a new process.
5915[clinic start generated code]*/
5916
Larry Hastings2f936352014-08-05 14:04:04 +10005917static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005918os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5919/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005920{
Steve Dowercc16be82016-09-08 10:35:16 -07005921 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005922 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005923 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005924 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005926
Victor Stinner8c62be82010-05-06 00:08:46 +00005927 /* spawnv has three arguments: (mode, path, argv), where
5928 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005929
Victor Stinner8c62be82010-05-06 00:08:46 +00005930 if (PyList_Check(argv)) {
5931 argc = PyList_Size(argv);
5932 getitem = PyList_GetItem;
5933 }
5934 else if (PyTuple_Check(argv)) {
5935 argc = PyTuple_Size(argv);
5936 getitem = PyTuple_GetItem;
5937 }
5938 else {
5939 PyErr_SetString(PyExc_TypeError,
5940 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005941 return NULL;
5942 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005943 if (argc == 0) {
5944 PyErr_SetString(PyExc_ValueError,
5945 "spawnv() arg 2 cannot be empty");
5946 return NULL;
5947 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005948
Steve Dowercc16be82016-09-08 10:35:16 -07005949 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 return PyErr_NoMemory();
5952 }
5953 for (i = 0; i < argc; i++) {
5954 if (!fsconvert_strdup((*getitem)(argv, i),
5955 &argvlist[i])) {
5956 free_string_array(argvlist, i);
5957 PyErr_SetString(
5958 PyExc_TypeError,
5959 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005960 return NULL;
5961 }
Steve Dower93ff8722016-11-19 19:03:54 -08005962 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005963 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005964 PyErr_SetString(
5965 PyExc_ValueError,
5966 "spawnv() arg 2 first element cannot be empty");
5967 return NULL;
5968 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005969 }
5970 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005971
pxinwrf2d7ac72019-05-21 18:46:37 +08005972#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005973 if (mode == _OLD_P_OVERLAY)
5974 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005975#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005976
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005977 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08005978 Py_None) < 0) {
5979 free_string_array(argvlist, argc);
5980 return NULL;
5981 }
5982
Victor Stinner8c62be82010-05-06 00:08:46 +00005983 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005984 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005985#ifdef HAVE_WSPAWNV
5986 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005987#elif defined(HAVE_RTPSPAWN)
5988 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07005989#else
5990 spawnval = _spawnv(mode, path->narrow, argvlist);
5991#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005992 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005993 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005994
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005996
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 if (spawnval == -1)
5998 return posix_error();
5999 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006000 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006001}
6002
Larry Hastings2f936352014-08-05 14:04:04 +10006003/*[clinic input]
6004os.spawnve
6005
6006 mode: int
6007 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006008 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006009 Path of executable file.
6010 argv: object
6011 Tuple or list of strings.
6012 env: object
6013 Dictionary of strings mapping to strings.
6014 /
6015
6016Execute the program specified by path in a new process.
6017[clinic start generated code]*/
6018
Larry Hastings2f936352014-08-05 14:04:04 +10006019static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006020os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006021 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006022/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006023{
Steve Dowercc16be82016-09-08 10:35:16 -07006024 EXECV_CHAR **argvlist;
6025 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006026 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006027 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006028 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006029 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006030 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006031
Victor Stinner8c62be82010-05-06 00:08:46 +00006032 /* spawnve has four arguments: (mode, path, argv, env), where
6033 argv is a list or tuple of strings and env is a dictionary
6034 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006035
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 if (PyList_Check(argv)) {
6037 argc = PyList_Size(argv);
6038 getitem = PyList_GetItem;
6039 }
6040 else if (PyTuple_Check(argv)) {
6041 argc = PyTuple_Size(argv);
6042 getitem = PyTuple_GetItem;
6043 }
6044 else {
6045 PyErr_SetString(PyExc_TypeError,
6046 "spawnve() arg 2 must be a tuple or list");
6047 goto fail_0;
6048 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006049 if (argc == 0) {
6050 PyErr_SetString(PyExc_ValueError,
6051 "spawnve() arg 2 cannot be empty");
6052 goto fail_0;
6053 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 if (!PyMapping_Check(env)) {
6055 PyErr_SetString(PyExc_TypeError,
6056 "spawnve() arg 3 must be a mapping object");
6057 goto fail_0;
6058 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006059
Steve Dowercc16be82016-09-08 10:35:16 -07006060 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006061 if (argvlist == NULL) {
6062 PyErr_NoMemory();
6063 goto fail_0;
6064 }
6065 for (i = 0; i < argc; i++) {
6066 if (!fsconvert_strdup((*getitem)(argv, i),
6067 &argvlist[i]))
6068 {
6069 lastarg = i;
6070 goto fail_1;
6071 }
Steve Dowerbce26262016-11-19 19:17:26 -08006072 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006073 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006074 PyErr_SetString(
6075 PyExc_ValueError,
6076 "spawnv() arg 2 first element cannot be empty");
6077 goto fail_1;
6078 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 }
6080 lastarg = argc;
6081 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006082
Victor Stinner8c62be82010-05-06 00:08:46 +00006083 envlist = parse_envlist(env, &envc);
6084 if (envlist == NULL)
6085 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006086
pxinwrf2d7ac72019-05-21 18:46:37 +08006087#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006088 if (mode == _OLD_P_OVERLAY)
6089 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006090#endif
Tim Peters25059d32001-12-07 20:35:43 +00006091
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006092 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006093 goto fail_2;
6094 }
6095
Victor Stinner8c62be82010-05-06 00:08:46 +00006096 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006097 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006098#ifdef HAVE_WSPAWNV
6099 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006100#elif defined(HAVE_RTPSPAWN)
6101 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6102 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006103#else
6104 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6105#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006106 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006107 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006108
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 if (spawnval == -1)
6110 (void) posix_error();
6111 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006112 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006113
Saiyang Gou95f60012020-02-04 16:15:00 -08006114 fail_2:
Victor Stinner8c62be82010-05-06 00:08:46 +00006115 while (--envc >= 0)
6116 PyMem_DEL(envlist[envc]);
6117 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006118 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006119 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006120 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006121 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006122}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006123
Guido van Rossuma1065681999-01-25 23:20:23 +00006124#endif /* HAVE_SPAWNV */
6125
6126
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006127#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006128
6129/* Helper function to validate arguments.
6130 Returns 0 on success. non-zero on failure with a TypeError raised.
6131 If obj is non-NULL it must be callable. */
6132static int
6133check_null_or_callable(PyObject *obj, const char* obj_name)
6134{
6135 if (obj && !PyCallable_Check(obj)) {
6136 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006137 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006138 return -1;
6139 }
6140 return 0;
6141}
6142
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006143/*[clinic input]
6144os.register_at_fork
6145
Gregory P. Smith163468a2017-05-29 10:03:41 -07006146 *
6147 before: object=NULL
6148 A callable to be called in the parent before the fork() syscall.
6149 after_in_child: object=NULL
6150 A callable to be called in the child after fork().
6151 after_in_parent: object=NULL
6152 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006153
Gregory P. Smith163468a2017-05-29 10:03:41 -07006154Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006155
Gregory P. Smith163468a2017-05-29 10:03:41 -07006156'before' callbacks are called in reverse order.
6157'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006158
6159[clinic start generated code]*/
6160
6161static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006162os_register_at_fork_impl(PyObject *module, PyObject *before,
6163 PyObject *after_in_child, PyObject *after_in_parent)
6164/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006165{
6166 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006167
Gregory P. Smith163468a2017-05-29 10:03:41 -07006168 if (!before && !after_in_child && !after_in_parent) {
6169 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6170 return NULL;
6171 }
6172 if (check_null_or_callable(before, "before") ||
6173 check_null_or_callable(after_in_child, "after_in_child") ||
6174 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006175 return NULL;
6176 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006177 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006178
Gregory P. Smith163468a2017-05-29 10:03:41 -07006179 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006180 return NULL;
6181 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006182 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006183 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006184 }
6185 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6186 return NULL;
6187 }
6188 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006189}
6190#endif /* HAVE_FORK */
6191
6192
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006193#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006194/*[clinic input]
6195os.fork1
6196
6197Fork a child process with a single multiplexed (i.e., not bound) thread.
6198
6199Return 0 to child process and PID of child to parent process.
6200[clinic start generated code]*/
6201
Larry Hastings2f936352014-08-05 14:04:04 +10006202static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006203os_fork1_impl(PyObject *module)
6204/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006205{
Victor Stinner8c62be82010-05-06 00:08:46 +00006206 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006207
Victor Stinner81a7be32020-04-14 15:14:01 +02006208 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006209 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6210 return NULL;
6211 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006212 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006213 pid = fork1();
6214 if (pid == 0) {
6215 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006216 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006217 } else {
6218 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006219 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 }
6221 if (pid == -1)
6222 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006224}
Larry Hastings2f936352014-08-05 14:04:04 +10006225#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006226
6227
Guido van Rossumad0ee831995-03-01 10:34:45 +00006228#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006229/*[clinic input]
6230os.fork
6231
6232Fork a child process.
6233
6234Return 0 to child process and PID of child to parent process.
6235[clinic start generated code]*/
6236
Larry Hastings2f936352014-08-05 14:04:04 +10006237static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006238os_fork_impl(PyObject *module)
6239/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006240{
Victor Stinner8c62be82010-05-06 00:08:46 +00006241 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006242 PyInterpreterState *interp = _PyInterpreterState_GET();
6243 if (interp->config._isolated_interpreter) {
6244 PyErr_SetString(PyExc_RuntimeError,
6245 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006246 return NULL;
6247 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006248 if (PySys_Audit("os.fork", NULL) < 0) {
6249 return NULL;
6250 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006251 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 pid = fork();
6253 if (pid == 0) {
6254 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006255 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006256 } else {
6257 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006258 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006259 }
6260 if (pid == -1)
6261 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006262 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006263}
Larry Hastings2f936352014-08-05 14:04:04 +10006264#endif /* HAVE_FORK */
6265
Guido van Rossum85e3b011991-06-03 12:42:10 +00006266
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006267#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006268#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006269/*[clinic input]
6270os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006271
Larry Hastings2f936352014-08-05 14:04:04 +10006272 policy: int
6273
6274Get the maximum scheduling priority for policy.
6275[clinic start generated code]*/
6276
Larry Hastings2f936352014-08-05 14:04:04 +10006277static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006278os_sched_get_priority_max_impl(PyObject *module, int policy)
6279/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006280{
6281 int max;
6282
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006283 max = sched_get_priority_max(policy);
6284 if (max < 0)
6285 return posix_error();
6286 return PyLong_FromLong(max);
6287}
6288
Larry Hastings2f936352014-08-05 14:04:04 +10006289
6290/*[clinic input]
6291os.sched_get_priority_min
6292
6293 policy: int
6294
6295Get the minimum scheduling priority for policy.
6296[clinic start generated code]*/
6297
Larry Hastings2f936352014-08-05 14:04:04 +10006298static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006299os_sched_get_priority_min_impl(PyObject *module, int policy)
6300/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006301{
6302 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006303 if (min < 0)
6304 return posix_error();
6305 return PyLong_FromLong(min);
6306}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006307#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6308
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006309
Larry Hastings2f936352014-08-05 14:04:04 +10006310#ifdef HAVE_SCHED_SETSCHEDULER
6311/*[clinic input]
6312os.sched_getscheduler
6313 pid: pid_t
6314 /
6315
Min ho Kimc4cacc82019-07-31 08:16:13 +10006316Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006317
6318Passing 0 for pid returns the scheduling policy for the calling process.
6319[clinic start generated code]*/
6320
Larry Hastings2f936352014-08-05 14:04:04 +10006321static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006322os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006323/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006324{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006325 int policy;
6326
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006327 policy = sched_getscheduler(pid);
6328 if (policy < 0)
6329 return posix_error();
6330 return PyLong_FromLong(policy);
6331}
Larry Hastings2f936352014-08-05 14:04:04 +10006332#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006333
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006334
William Orr81574b82018-10-01 22:19:56 -07006335#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006336/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006337class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006338
6339@classmethod
6340os.sched_param.__new__
6341
6342 sched_priority: object
6343 A scheduling parameter.
6344
Eddie Elizondob3966632019-11-05 07:16:14 -08006345Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006346[clinic start generated code]*/
6347
Larry Hastings2f936352014-08-05 14:04:04 +10006348static PyObject *
6349os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006350/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006351{
6352 PyObject *res;
6353
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006354 res = PyStructSequence_New(type);
6355 if (!res)
6356 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006357 Py_INCREF(sched_priority);
6358 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006359 return res;
6360}
6361
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006362PyDoc_VAR(os_sched_param__doc__);
6363
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006364static PyStructSequence_Field sched_param_fields[] = {
6365 {"sched_priority", "the scheduling priority"},
6366 {0}
6367};
6368
6369static PyStructSequence_Desc sched_param_desc = {
6370 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006371 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006372 sched_param_fields,
6373 1
6374};
6375
6376static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006377convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006378{
6379 long priority;
6380
Victor Stinner1c2fa782020-05-10 11:05:29 +02006381 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006382 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6383 return 0;
6384 }
6385 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6386 if (priority == -1 && PyErr_Occurred())
6387 return 0;
6388 if (priority > INT_MAX || priority < INT_MIN) {
6389 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6390 return 0;
6391 }
6392 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6393 return 1;
6394}
William Orr81574b82018-10-01 22:19:56 -07006395#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006396
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006397
6398#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006399/*[clinic input]
6400os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006401
Larry Hastings2f936352014-08-05 14:04:04 +10006402 pid: pid_t
6403 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006404 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006405 /
6406
6407Set the scheduling policy for the process identified by pid.
6408
6409If pid is 0, the calling process is changed.
6410param is an instance of sched_param.
6411[clinic start generated code]*/
6412
Larry Hastings2f936352014-08-05 14:04:04 +10006413static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006414os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006415 PyObject *param_obj)
6416/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006417{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006418 struct sched_param param;
6419 if (!convert_sched_param(module, param_obj, &param)) {
6420 return NULL;
6421 }
6422
Jesus Cea9c822272011-09-10 01:40:52 +02006423 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006424 ** sched_setscheduler() returns 0 in Linux, but the previous
6425 ** scheduling policy under Solaris/Illumos, and others.
6426 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006427 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006428 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006429 return posix_error();
6430 Py_RETURN_NONE;
6431}
Larry Hastings2f936352014-08-05 14:04:04 +10006432#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006433
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006434
6435#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006436/*[clinic input]
6437os.sched_getparam
6438 pid: pid_t
6439 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006440
Larry Hastings2f936352014-08-05 14:04:04 +10006441Returns scheduling parameters for the process identified by pid.
6442
6443If pid is 0, returns parameters for the calling process.
6444Return value is an instance of sched_param.
6445[clinic start generated code]*/
6446
Larry Hastings2f936352014-08-05 14:04:04 +10006447static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006448os_sched_getparam_impl(PyObject *module, pid_t pid)
6449/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006450{
6451 struct sched_param param;
6452 PyObject *result;
6453 PyObject *priority;
6454
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006455 if (sched_getparam(pid, &param))
6456 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006457 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006458 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006459 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006460 return NULL;
6461 priority = PyLong_FromLong(param.sched_priority);
6462 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006463 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006464 return NULL;
6465 }
Larry Hastings2f936352014-08-05 14:04:04 +10006466 PyStructSequence_SET_ITEM(result, 0, priority);
6467 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006468}
6469
Larry Hastings2f936352014-08-05 14:04:04 +10006470
6471/*[clinic input]
6472os.sched_setparam
6473 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006474 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006475 /
6476
6477Set scheduling parameters for the process identified by pid.
6478
6479If pid is 0, sets parameters for the calling process.
6480param should be an instance of sched_param.
6481[clinic start generated code]*/
6482
Larry Hastings2f936352014-08-05 14:04:04 +10006483static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006484os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6485/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006486{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006487 struct sched_param param;
6488 if (!convert_sched_param(module, param_obj, &param)) {
6489 return NULL;
6490 }
6491
6492 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006493 return posix_error();
6494 Py_RETURN_NONE;
6495}
Larry Hastings2f936352014-08-05 14:04:04 +10006496#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006497
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006498
6499#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006500/*[clinic input]
6501os.sched_rr_get_interval -> double
6502 pid: pid_t
6503 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006504
Larry Hastings2f936352014-08-05 14:04:04 +10006505Return the round-robin quantum for the process identified by pid, in seconds.
6506
6507Value returned is a float.
6508[clinic start generated code]*/
6509
Larry Hastings2f936352014-08-05 14:04:04 +10006510static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006511os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6512/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006513{
6514 struct timespec interval;
6515 if (sched_rr_get_interval(pid, &interval)) {
6516 posix_error();
6517 return -1.0;
6518 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006519#ifdef _Py_MEMORY_SANITIZER
6520 __msan_unpoison(&interval, sizeof(interval));
6521#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006522 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6523}
6524#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006525
Larry Hastings2f936352014-08-05 14:04:04 +10006526
6527/*[clinic input]
6528os.sched_yield
6529
6530Voluntarily relinquish the CPU.
6531[clinic start generated code]*/
6532
Larry Hastings2f936352014-08-05 14:04:04 +10006533static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006534os_sched_yield_impl(PyObject *module)
6535/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006536{
6537 if (sched_yield())
6538 return posix_error();
6539 Py_RETURN_NONE;
6540}
6541
Benjamin Peterson2740af82011-08-02 17:41:34 -05006542#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006543/* The minimum number of CPUs allocated in a cpu_set_t */
6544static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006545
Larry Hastings2f936352014-08-05 14:04:04 +10006546/*[clinic input]
6547os.sched_setaffinity
6548 pid: pid_t
6549 mask : object
6550 /
6551
6552Set the CPU affinity of the process identified by pid to mask.
6553
6554mask should be an iterable of integers identifying CPUs.
6555[clinic start generated code]*/
6556
Larry Hastings2f936352014-08-05 14:04:04 +10006557static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006558os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6559/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006560{
Antoine Pitrou84869872012-08-04 16:16:35 +02006561 int ncpus;
6562 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006563 cpu_set_t *cpu_set = NULL;
6564 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006565
Larry Hastings2f936352014-08-05 14:04:04 +10006566 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006567 if (iterator == NULL)
6568 return NULL;
6569
6570 ncpus = NCPUS_START;
6571 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006572 cpu_set = CPU_ALLOC(ncpus);
6573 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006574 PyErr_NoMemory();
6575 goto error;
6576 }
Larry Hastings2f936352014-08-05 14:04:04 +10006577 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006578
6579 while ((item = PyIter_Next(iterator))) {
6580 long cpu;
6581 if (!PyLong_Check(item)) {
6582 PyErr_Format(PyExc_TypeError,
6583 "expected an iterator of ints, "
6584 "but iterator yielded %R",
6585 Py_TYPE(item));
6586 Py_DECREF(item);
6587 goto error;
6588 }
6589 cpu = PyLong_AsLong(item);
6590 Py_DECREF(item);
6591 if (cpu < 0) {
6592 if (!PyErr_Occurred())
6593 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6594 goto error;
6595 }
6596 if (cpu > INT_MAX - 1) {
6597 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6598 goto error;
6599 }
6600 if (cpu >= ncpus) {
6601 /* Grow CPU mask to fit the CPU number */
6602 int newncpus = ncpus;
6603 cpu_set_t *newmask;
6604 size_t newsetsize;
6605 while (newncpus <= cpu) {
6606 if (newncpus > INT_MAX / 2)
6607 newncpus = cpu + 1;
6608 else
6609 newncpus = newncpus * 2;
6610 }
6611 newmask = CPU_ALLOC(newncpus);
6612 if (newmask == NULL) {
6613 PyErr_NoMemory();
6614 goto error;
6615 }
6616 newsetsize = CPU_ALLOC_SIZE(newncpus);
6617 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006618 memcpy(newmask, cpu_set, setsize);
6619 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006620 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006621 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006622 ncpus = newncpus;
6623 }
Larry Hastings2f936352014-08-05 14:04:04 +10006624 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006625 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07006626 if (PyErr_Occurred()) {
6627 goto error;
6628 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006629 Py_CLEAR(iterator);
6630
Larry Hastings2f936352014-08-05 14:04:04 +10006631 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006632 posix_error();
6633 goto error;
6634 }
Larry Hastings2f936352014-08-05 14:04:04 +10006635 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006636 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006637
6638error:
Larry Hastings2f936352014-08-05 14:04:04 +10006639 if (cpu_set)
6640 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006641 Py_XDECREF(iterator);
6642 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006643}
6644
Larry Hastings2f936352014-08-05 14:04:04 +10006645
6646/*[clinic input]
6647os.sched_getaffinity
6648 pid: pid_t
6649 /
6650
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006651Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006652
6653The affinity is returned as a set of CPU identifiers.
6654[clinic start generated code]*/
6655
Larry Hastings2f936352014-08-05 14:04:04 +10006656static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006657os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006658/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006659{
Antoine Pitrou84869872012-08-04 16:16:35 +02006660 int cpu, ncpus, count;
6661 size_t setsize;
6662 cpu_set_t *mask = NULL;
6663 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006664
Antoine Pitrou84869872012-08-04 16:16:35 +02006665 ncpus = NCPUS_START;
6666 while (1) {
6667 setsize = CPU_ALLOC_SIZE(ncpus);
6668 mask = CPU_ALLOC(ncpus);
6669 if (mask == NULL)
6670 return PyErr_NoMemory();
6671 if (sched_getaffinity(pid, setsize, mask) == 0)
6672 break;
6673 CPU_FREE(mask);
6674 if (errno != EINVAL)
6675 return posix_error();
6676 if (ncpus > INT_MAX / 2) {
6677 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6678 "a large enough CPU set");
6679 return NULL;
6680 }
6681 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006682 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006683
6684 res = PySet_New(NULL);
6685 if (res == NULL)
6686 goto error;
6687 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6688 if (CPU_ISSET_S(cpu, setsize, mask)) {
6689 PyObject *cpu_num = PyLong_FromLong(cpu);
6690 --count;
6691 if (cpu_num == NULL)
6692 goto error;
6693 if (PySet_Add(res, cpu_num)) {
6694 Py_DECREF(cpu_num);
6695 goto error;
6696 }
6697 Py_DECREF(cpu_num);
6698 }
6699 }
6700 CPU_FREE(mask);
6701 return res;
6702
6703error:
6704 if (mask)
6705 CPU_FREE(mask);
6706 Py_XDECREF(res);
6707 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006708}
6709
Benjamin Peterson2740af82011-08-02 17:41:34 -05006710#endif /* HAVE_SCHED_SETAFFINITY */
6711
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006712#endif /* HAVE_SCHED_H */
6713
Larry Hastings2f936352014-08-05 14:04:04 +10006714
Neal Norwitzb59798b2003-03-21 01:43:31 +00006715/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006716/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6717#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006718#define DEV_PTY_FILE "/dev/ptc"
6719#define HAVE_DEV_PTMX
6720#else
6721#define DEV_PTY_FILE "/dev/ptmx"
6722#endif
6723
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006724#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006725#ifdef HAVE_PTY_H
6726#include <pty.h>
6727#else
6728#ifdef HAVE_LIBUTIL_H
6729#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006730#else
6731#ifdef HAVE_UTIL_H
6732#include <util.h>
6733#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006734#endif /* HAVE_LIBUTIL_H */
6735#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006736#ifdef HAVE_STROPTS_H
6737#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006738#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006739#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006740
Larry Hastings2f936352014-08-05 14:04:04 +10006741
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006742#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006743/*[clinic input]
6744os.openpty
6745
6746Open a pseudo-terminal.
6747
6748Return a tuple of (master_fd, slave_fd) containing open file descriptors
6749for both the master and slave ends.
6750[clinic start generated code]*/
6751
Larry Hastings2f936352014-08-05 14:04:04 +10006752static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006753os_openpty_impl(PyObject *module)
6754/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006755{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006756 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006757#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006759#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006760#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006762#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006764#endif
6765#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006766
Thomas Wouters70c21a12000-07-14 14:28:33 +00006767#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006768 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006769 goto posix_error;
6770
6771 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6772 goto error;
6773 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6774 goto error;
6775
Neal Norwitzb59798b2003-03-21 01:43:31 +00006776#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6778 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006779 goto posix_error;
6780 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6781 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006782
Victor Stinnerdaf45552013-08-28 00:53:59 +02006783 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006785 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006786
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006787#else
Victor Stinner000de532013-11-25 23:19:58 +01006788 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006790 goto posix_error;
6791
Victor Stinner8c62be82010-05-06 00:08:46 +00006792 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006793
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 /* change permission of slave */
6795 if (grantpt(master_fd) < 0) {
6796 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006797 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006798 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006799
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 /* unlock slave */
6801 if (unlockpt(master_fd) < 0) {
6802 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006803 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006805
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006807
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 slave_name = ptsname(master_fd); /* get name of slave */
6809 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006810 goto posix_error;
6811
6812 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006813 if (slave_fd == -1)
6814 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006815
6816 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6817 goto posix_error;
6818
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006819#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6821 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006822#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006824#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006825#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006826#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006827
Victor Stinner8c62be82010-05-06 00:08:46 +00006828 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006829
Victor Stinnerdaf45552013-08-28 00:53:59 +02006830posix_error:
6831 posix_error();
6832error:
6833 if (master_fd != -1)
6834 close(master_fd);
6835 if (slave_fd != -1)
6836 close(slave_fd);
6837 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006838}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006839#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006840
Larry Hastings2f936352014-08-05 14:04:04 +10006841
Fred Drake8cef4cf2000-06-28 16:40:38 +00006842#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006843/*[clinic input]
6844os.forkpty
6845
6846Fork a new process with a new pseudo-terminal as controlling tty.
6847
6848Returns a tuple of (pid, master_fd).
6849Like fork(), return pid of 0 to the child process,
6850and pid of child to the parent process.
6851To both, return fd of newly opened pseudo-terminal.
6852[clinic start generated code]*/
6853
Larry Hastings2f936352014-08-05 14:04:04 +10006854static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006855os_forkpty_impl(PyObject *module)
6856/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006857{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006858 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006860
Victor Stinner81a7be32020-04-14 15:14:01 +02006861 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006862 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6863 return NULL;
6864 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006865 if (PySys_Audit("os.forkpty", NULL) < 0) {
6866 return NULL;
6867 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006868 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 pid = forkpty(&master_fd, NULL, NULL, NULL);
6870 if (pid == 0) {
6871 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006872 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 } else {
6874 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006875 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006876 }
6877 if (pid == -1)
6878 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006879 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006880}
Larry Hastings2f936352014-08-05 14:04:04 +10006881#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006882
Ross Lagerwall7807c352011-03-17 20:20:30 +02006883
Guido van Rossumad0ee831995-03-01 10:34:45 +00006884#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006885/*[clinic input]
6886os.getegid
6887
6888Return the current process's effective group id.
6889[clinic start generated code]*/
6890
Larry Hastings2f936352014-08-05 14:04:04 +10006891static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006892os_getegid_impl(PyObject *module)
6893/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006894{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006895 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006896}
Larry Hastings2f936352014-08-05 14:04:04 +10006897#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006898
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006899
Guido van Rossumad0ee831995-03-01 10:34:45 +00006900#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006901/*[clinic input]
6902os.geteuid
6903
6904Return the current process's effective user id.
6905[clinic start generated code]*/
6906
Larry Hastings2f936352014-08-05 14:04:04 +10006907static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006908os_geteuid_impl(PyObject *module)
6909/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006910{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006911 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006912}
Larry Hastings2f936352014-08-05 14:04:04 +10006913#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006914
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006915
Guido van Rossumad0ee831995-03-01 10:34:45 +00006916#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006917/*[clinic input]
6918os.getgid
6919
6920Return the current process's group id.
6921[clinic start generated code]*/
6922
Larry Hastings2f936352014-08-05 14:04:04 +10006923static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006924os_getgid_impl(PyObject *module)
6925/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006926{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006927 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006928}
Larry Hastings2f936352014-08-05 14:04:04 +10006929#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006930
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006931
Berker Peksag39404992016-09-15 20:45:16 +03006932#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006933/*[clinic input]
6934os.getpid
6935
6936Return the current process id.
6937[clinic start generated code]*/
6938
Larry Hastings2f936352014-08-05 14:04:04 +10006939static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006940os_getpid_impl(PyObject *module)
6941/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006942{
Victor Stinner8c62be82010-05-06 00:08:46 +00006943 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006944}
Berker Peksag39404992016-09-15 20:45:16 +03006945#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006946
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006947#ifdef NGROUPS_MAX
6948#define MAX_GROUPS NGROUPS_MAX
6949#else
6950 /* defined to be 16 on Solaris7, so this should be a small number */
6951#define MAX_GROUPS 64
6952#endif
6953
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006954#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006955
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006956#ifdef __APPLE__
6957/*[clinic input]
6958os.getgrouplist
6959
6960 user: str
6961 username to lookup
6962 group as basegid: int
6963 base group id of the user
6964 /
6965
6966Returns a list of groups to which a user belongs.
6967[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006968
6969static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006970os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
6971/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
6972#else
6973/*[clinic input]
6974os.getgrouplist
6975
6976 user: str
6977 username to lookup
6978 group as basegid: gid_t
6979 base group id of the user
6980 /
6981
6982Returns a list of groups to which a user belongs.
6983[clinic start generated code]*/
6984
6985static PyObject *
6986os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
6987/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
6988#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006989{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006990 int i, ngroups;
6991 PyObject *list;
6992#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006993 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006994#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006995 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006996#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006997
6998 /*
6999 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7000 * number of supplimental groups a users can belong to.
7001 * We have to increment it by one because
7002 * getgrouplist() returns both the supplemental groups
7003 * and the primary group, i.e. all of the groups the
7004 * user belongs to.
7005 */
7006 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007007
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007008 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007009#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007010 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007011#else
7012 groups = PyMem_New(gid_t, ngroups);
7013#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007014 if (groups == NULL) {
7015 return PyErr_NoMemory();
7016 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007017
7018 int old_ngroups = ngroups;
7019 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7020 /* Success */
7021 break;
7022 }
7023
7024 /* getgrouplist() fails if the group list is too small */
7025 PyMem_Free(groups);
7026
7027 if (ngroups > old_ngroups) {
7028 /* If the group list is too small, the glibc implementation of
7029 getgrouplist() sets ngroups to the total number of groups and
7030 returns -1. */
7031 }
7032 else {
7033 /* Double the group list size */
7034 if (ngroups > INT_MAX / 2) {
7035 return PyErr_NoMemory();
7036 }
7037 ngroups *= 2;
7038 }
7039
7040 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007041 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007042
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007043#ifdef _Py_MEMORY_SANITIZER
7044 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7045 __msan_unpoison(&ngroups, sizeof(ngroups));
7046 __msan_unpoison(groups, ngroups*sizeof(*groups));
7047#endif
7048
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007049 list = PyList_New(ngroups);
7050 if (list == NULL) {
7051 PyMem_Del(groups);
7052 return NULL;
7053 }
7054
7055 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007056#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007057 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007058#else
7059 PyObject *o = _PyLong_FromGid(groups[i]);
7060#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007061 if (o == NULL) {
7062 Py_DECREF(list);
7063 PyMem_Del(groups);
7064 return NULL;
7065 }
7066 PyList_SET_ITEM(list, i, o);
7067 }
7068
7069 PyMem_Del(groups);
7070
7071 return list;
7072}
Larry Hastings2f936352014-08-05 14:04:04 +10007073#endif /* HAVE_GETGROUPLIST */
7074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007075
Fred Drakec9680921999-12-13 16:37:25 +00007076#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007077/*[clinic input]
7078os.getgroups
7079
7080Return list of supplemental group IDs for the process.
7081[clinic start generated code]*/
7082
Larry Hastings2f936352014-08-05 14:04:04 +10007083static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007084os_getgroups_impl(PyObject *module)
7085/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007086{
7087 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007088 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007089
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007090 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007091 * This is a helper variable to store the intermediate result when
7092 * that happens.
7093 *
7094 * To keep the code readable the OSX behaviour is unconditional,
7095 * according to the POSIX spec this should be safe on all unix-y
7096 * systems.
7097 */
7098 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007100
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007101#ifdef __APPLE__
7102 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7103 * there are more groups than can fit in grouplist. Therefore, on OS X
7104 * always first call getgroups with length 0 to get the actual number
7105 * of groups.
7106 */
7107 n = getgroups(0, NULL);
7108 if (n < 0) {
7109 return posix_error();
7110 } else if (n <= MAX_GROUPS) {
7111 /* groups will fit in existing array */
7112 alt_grouplist = grouplist;
7113 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007114 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007115 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007116 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007117 }
7118 }
7119
7120 n = getgroups(n, alt_grouplist);
7121 if (n == -1) {
7122 if (alt_grouplist != grouplist) {
7123 PyMem_Free(alt_grouplist);
7124 }
7125 return posix_error();
7126 }
7127#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007128 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007129 if (n < 0) {
7130 if (errno == EINVAL) {
7131 n = getgroups(0, NULL);
7132 if (n == -1) {
7133 return posix_error();
7134 }
7135 if (n == 0) {
7136 /* Avoid malloc(0) */
7137 alt_grouplist = grouplist;
7138 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007139 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007140 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007141 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007142 }
7143 n = getgroups(n, alt_grouplist);
7144 if (n == -1) {
7145 PyMem_Free(alt_grouplist);
7146 return posix_error();
7147 }
7148 }
7149 } else {
7150 return posix_error();
7151 }
7152 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007153#endif
7154
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007155 result = PyList_New(n);
7156 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007157 int i;
7158 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007159 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007160 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007161 Py_DECREF(result);
7162 result = NULL;
7163 break;
Fred Drakec9680921999-12-13 16:37:25 +00007164 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007166 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007167 }
7168
7169 if (alt_grouplist != grouplist) {
7170 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007171 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007172
Fred Drakec9680921999-12-13 16:37:25 +00007173 return result;
7174}
Larry Hastings2f936352014-08-05 14:04:04 +10007175#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007176
Antoine Pitroub7572f02009-12-02 20:46:48 +00007177#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007178#ifdef __APPLE__
7179/*[clinic input]
7180os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007181
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007182 username as oname: FSConverter
7183 gid: int
7184 /
7185
7186Initialize the group access list.
7187
7188Call the system initgroups() to initialize the group access list with all of
7189the groups of which the specified username is a member, plus the specified
7190group id.
7191[clinic start generated code]*/
7192
Antoine Pitroub7572f02009-12-02 20:46:48 +00007193static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007194os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7195/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7196#else
7197/*[clinic input]
7198os.initgroups
7199
7200 username as oname: FSConverter
7201 gid: gid_t
7202 /
7203
7204Initialize the group access list.
7205
7206Call the system initgroups() to initialize the group access list with all of
7207the groups of which the specified username is a member, plus the specified
7208group id.
7209[clinic start generated code]*/
7210
7211static PyObject *
7212os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7213/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7214#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007215{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007216 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007217
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007218 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007219 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007220
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007221 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007222}
Larry Hastings2f936352014-08-05 14:04:04 +10007223#endif /* HAVE_INITGROUPS */
7224
Antoine Pitroub7572f02009-12-02 20:46:48 +00007225
Martin v. Löwis606edc12002-06-13 21:09:11 +00007226#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007227/*[clinic input]
7228os.getpgid
7229
7230 pid: pid_t
7231
7232Call the system call getpgid(), and return the result.
7233[clinic start generated code]*/
7234
Larry Hastings2f936352014-08-05 14:04:04 +10007235static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007236os_getpgid_impl(PyObject *module, pid_t pid)
7237/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007238{
7239 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 if (pgid < 0)
7241 return posix_error();
7242 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007243}
7244#endif /* HAVE_GETPGID */
7245
7246
Guido van Rossumb6775db1994-08-01 11:34:53 +00007247#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007248/*[clinic input]
7249os.getpgrp
7250
7251Return the current process group id.
7252[clinic start generated code]*/
7253
Larry Hastings2f936352014-08-05 14:04:04 +10007254static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007255os_getpgrp_impl(PyObject *module)
7256/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007257{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007258#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007259 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007260#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007261 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007262#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007263}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007264#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007265
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007266
Guido van Rossumb6775db1994-08-01 11:34:53 +00007267#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007268/*[clinic input]
7269os.setpgrp
7270
7271Make the current process the leader of its process group.
7272[clinic start generated code]*/
7273
Larry Hastings2f936352014-08-05 14:04:04 +10007274static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007275os_setpgrp_impl(PyObject *module)
7276/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007277{
Guido van Rossum64933891994-10-20 21:56:42 +00007278#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007279 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007280#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007281 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007282#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007283 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007284 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007285}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007286#endif /* HAVE_SETPGRP */
7287
Guido van Rossumad0ee831995-03-01 10:34:45 +00007288#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007289
7290#ifdef MS_WINDOWS
7291#include <tlhelp32.h>
7292
7293static PyObject*
7294win32_getppid()
7295{
7296 HANDLE snapshot;
7297 pid_t mypid;
7298 PyObject* result = NULL;
7299 BOOL have_record;
7300 PROCESSENTRY32 pe;
7301
7302 mypid = getpid(); /* This function never fails */
7303
7304 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7305 if (snapshot == INVALID_HANDLE_VALUE)
7306 return PyErr_SetFromWindowsErr(GetLastError());
7307
7308 pe.dwSize = sizeof(pe);
7309 have_record = Process32First(snapshot, &pe);
7310 while (have_record) {
7311 if (mypid == (pid_t)pe.th32ProcessID) {
7312 /* We could cache the ulong value in a static variable. */
7313 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7314 break;
7315 }
7316
7317 have_record = Process32Next(snapshot, &pe);
7318 }
7319
7320 /* If our loop exits and our pid was not found (result will be NULL)
7321 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7322 * error anyway, so let's raise it. */
7323 if (!result)
7324 result = PyErr_SetFromWindowsErr(GetLastError());
7325
7326 CloseHandle(snapshot);
7327
7328 return result;
7329}
7330#endif /*MS_WINDOWS*/
7331
Larry Hastings2f936352014-08-05 14:04:04 +10007332
7333/*[clinic input]
7334os.getppid
7335
7336Return the parent's process id.
7337
7338If the parent process has already exited, Windows machines will still
7339return its id; others systems will return the id of the 'init' process (1).
7340[clinic start generated code]*/
7341
Larry Hastings2f936352014-08-05 14:04:04 +10007342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007343os_getppid_impl(PyObject *module)
7344/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007345{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007346#ifdef MS_WINDOWS
7347 return win32_getppid();
7348#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007349 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007350#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007351}
7352#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007353
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007354
Fred Drake12c6e2d1999-12-14 21:25:03 +00007355#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007356/*[clinic input]
7357os.getlogin
7358
7359Return the actual login name.
7360[clinic start generated code]*/
7361
Larry Hastings2f936352014-08-05 14:04:04 +10007362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007363os_getlogin_impl(PyObject *module)
7364/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007365{
Victor Stinner8c62be82010-05-06 00:08:46 +00007366 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007367#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007368 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007369 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007370
7371 if (GetUserNameW(user_name, &num_chars)) {
7372 /* num_chars is the number of unicode chars plus null terminator */
7373 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007374 }
7375 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007376 result = PyErr_SetFromWindowsErr(GetLastError());
7377#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007378 char *name;
7379 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007380
Victor Stinner8c62be82010-05-06 00:08:46 +00007381 errno = 0;
7382 name = getlogin();
7383 if (name == NULL) {
7384 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007385 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007386 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007387 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007388 }
7389 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007390 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007391 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007392#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007393 return result;
7394}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007395#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007396
Larry Hastings2f936352014-08-05 14:04:04 +10007397
Guido van Rossumad0ee831995-03-01 10:34:45 +00007398#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007399/*[clinic input]
7400os.getuid
7401
7402Return the current process's user id.
7403[clinic start generated code]*/
7404
Larry Hastings2f936352014-08-05 14:04:04 +10007405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007406os_getuid_impl(PyObject *module)
7407/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007408{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007409 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007410}
Larry Hastings2f936352014-08-05 14:04:04 +10007411#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007412
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007413
Brian Curtineb24d742010-04-12 17:16:38 +00007414#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007415#define HAVE_KILL
7416#endif /* MS_WINDOWS */
7417
7418#ifdef HAVE_KILL
7419/*[clinic input]
7420os.kill
7421
7422 pid: pid_t
7423 signal: Py_ssize_t
7424 /
7425
7426Kill a process with a signal.
7427[clinic start generated code]*/
7428
Larry Hastings2f936352014-08-05 14:04:04 +10007429static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007430os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7431/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007432{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007433 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7434 return NULL;
7435 }
7436#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007437 if (kill(pid, (int)signal) == -1)
7438 return posix_error();
7439 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007440#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007441 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007442 DWORD sig = (DWORD)signal;
7443 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007444 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007445
Victor Stinner8c62be82010-05-06 00:08:46 +00007446 /* Console processes which share a common console can be sent CTRL+C or
7447 CTRL+BREAK events, provided they handle said events. */
7448 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007449 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007450 err = GetLastError();
7451 PyErr_SetFromWindowsErr(err);
7452 }
7453 else
7454 Py_RETURN_NONE;
7455 }
Brian Curtineb24d742010-04-12 17:16:38 +00007456
Victor Stinner8c62be82010-05-06 00:08:46 +00007457 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7458 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007459 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007460 if (handle == NULL) {
7461 err = GetLastError();
7462 return PyErr_SetFromWindowsErr(err);
7463 }
Brian Curtineb24d742010-04-12 17:16:38 +00007464
Victor Stinner8c62be82010-05-06 00:08:46 +00007465 if (TerminateProcess(handle, sig) == 0) {
7466 err = GetLastError();
7467 result = PyErr_SetFromWindowsErr(err);
7468 } else {
7469 Py_INCREF(Py_None);
7470 result = Py_None;
7471 }
Brian Curtineb24d742010-04-12 17:16:38 +00007472
Victor Stinner8c62be82010-05-06 00:08:46 +00007473 CloseHandle(handle);
7474 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007475#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007476}
Larry Hastings2f936352014-08-05 14:04:04 +10007477#endif /* HAVE_KILL */
7478
7479
7480#ifdef HAVE_KILLPG
7481/*[clinic input]
7482os.killpg
7483
7484 pgid: pid_t
7485 signal: int
7486 /
7487
7488Kill a process group with a signal.
7489[clinic start generated code]*/
7490
Larry Hastings2f936352014-08-05 14:04:04 +10007491static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007492os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7493/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007494{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007495 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7496 return NULL;
7497 }
Larry Hastings2f936352014-08-05 14:04:04 +10007498 /* XXX some man pages make the `pgid` parameter an int, others
7499 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7500 take the same type. Moreover, pid_t is always at least as wide as
7501 int (else compilation of this module fails), which is safe. */
7502 if (killpg(pgid, signal) == -1)
7503 return posix_error();
7504 Py_RETURN_NONE;
7505}
7506#endif /* HAVE_KILLPG */
7507
Brian Curtineb24d742010-04-12 17:16:38 +00007508
Guido van Rossumc0125471996-06-28 18:55:32 +00007509#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007510#ifdef HAVE_SYS_LOCK_H
7511#include <sys/lock.h>
7512#endif
7513
Larry Hastings2f936352014-08-05 14:04:04 +10007514/*[clinic input]
7515os.plock
7516 op: int
7517 /
7518
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007519Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007520[clinic start generated code]*/
7521
Larry Hastings2f936352014-08-05 14:04:04 +10007522static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007523os_plock_impl(PyObject *module, int op)
7524/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007525{
Victor Stinner8c62be82010-05-06 00:08:46 +00007526 if (plock(op) == -1)
7527 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007528 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007529}
Larry Hastings2f936352014-08-05 14:04:04 +10007530#endif /* HAVE_PLOCK */
7531
Guido van Rossumc0125471996-06-28 18:55:32 +00007532
Guido van Rossumb6775db1994-08-01 11:34:53 +00007533#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007534/*[clinic input]
7535os.setuid
7536
7537 uid: uid_t
7538 /
7539
7540Set the current process's user id.
7541[clinic start generated code]*/
7542
Larry Hastings2f936352014-08-05 14:04:04 +10007543static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007544os_setuid_impl(PyObject *module, uid_t uid)
7545/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007546{
Victor Stinner8c62be82010-05-06 00:08:46 +00007547 if (setuid(uid) < 0)
7548 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007549 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007550}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007551#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007552
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007553
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007554#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007555/*[clinic input]
7556os.seteuid
7557
7558 euid: uid_t
7559 /
7560
7561Set the current process's effective user id.
7562[clinic start generated code]*/
7563
Larry Hastings2f936352014-08-05 14:04:04 +10007564static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007565os_seteuid_impl(PyObject *module, uid_t euid)
7566/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007567{
7568 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007569 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007570 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007571}
7572#endif /* HAVE_SETEUID */
7573
Larry Hastings2f936352014-08-05 14:04:04 +10007574
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007575#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007576/*[clinic input]
7577os.setegid
7578
7579 egid: gid_t
7580 /
7581
7582Set the current process's effective group id.
7583[clinic start generated code]*/
7584
Larry Hastings2f936352014-08-05 14:04:04 +10007585static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007586os_setegid_impl(PyObject *module, gid_t egid)
7587/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007588{
7589 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007590 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007591 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007592}
7593#endif /* HAVE_SETEGID */
7594
Larry Hastings2f936352014-08-05 14:04:04 +10007595
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007596#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007597/*[clinic input]
7598os.setreuid
7599
7600 ruid: uid_t
7601 euid: uid_t
7602 /
7603
7604Set the current process's real and effective user ids.
7605[clinic start generated code]*/
7606
Larry Hastings2f936352014-08-05 14:04:04 +10007607static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007608os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7609/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007610{
Victor Stinner8c62be82010-05-06 00:08:46 +00007611 if (setreuid(ruid, euid) < 0) {
7612 return posix_error();
7613 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007614 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007615 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007616}
7617#endif /* HAVE_SETREUID */
7618
Larry Hastings2f936352014-08-05 14:04:04 +10007619
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007620#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007621/*[clinic input]
7622os.setregid
7623
7624 rgid: gid_t
7625 egid: gid_t
7626 /
7627
7628Set the current process's real and effective group ids.
7629[clinic start generated code]*/
7630
Larry Hastings2f936352014-08-05 14:04:04 +10007631static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007632os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7633/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007634{
7635 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007636 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007637 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007638}
7639#endif /* HAVE_SETREGID */
7640
Larry Hastings2f936352014-08-05 14:04:04 +10007641
Guido van Rossumb6775db1994-08-01 11:34:53 +00007642#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007643/*[clinic input]
7644os.setgid
7645 gid: gid_t
7646 /
7647
7648Set the current process's group id.
7649[clinic start generated code]*/
7650
Larry Hastings2f936352014-08-05 14:04:04 +10007651static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007652os_setgid_impl(PyObject *module, gid_t gid)
7653/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007654{
Victor Stinner8c62be82010-05-06 00:08:46 +00007655 if (setgid(gid) < 0)
7656 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007657 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007658}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007659#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007660
Larry Hastings2f936352014-08-05 14:04:04 +10007661
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007662#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007663/*[clinic input]
7664os.setgroups
7665
7666 groups: object
7667 /
7668
7669Set the groups of the current process to list.
7670[clinic start generated code]*/
7671
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007672static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007673os_setgroups(PyObject *module, PyObject *groups)
7674/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007675{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007676 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007677 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007678
Victor Stinner8c62be82010-05-06 00:08:46 +00007679 if (!PySequence_Check(groups)) {
7680 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7681 return NULL;
7682 }
7683 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007684 if (len < 0) {
7685 return NULL;
7686 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007687 if (len > MAX_GROUPS) {
7688 PyErr_SetString(PyExc_ValueError, "too many groups");
7689 return NULL;
7690 }
7691 for(i = 0; i < len; i++) {
7692 PyObject *elem;
7693 elem = PySequence_GetItem(groups, i);
7694 if (!elem)
7695 return NULL;
7696 if (!PyLong_Check(elem)) {
7697 PyErr_SetString(PyExc_TypeError,
7698 "groups must be integers");
7699 Py_DECREF(elem);
7700 return NULL;
7701 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007702 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007703 Py_DECREF(elem);
7704 return NULL;
7705 }
7706 }
7707 Py_DECREF(elem);
7708 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007709
Victor Stinner8c62be82010-05-06 00:08:46 +00007710 if (setgroups(len, grouplist) < 0)
7711 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007712 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007713}
7714#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007715
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007716#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7717static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02007718wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007719{
Victor Stinner8c62be82010-05-06 00:08:46 +00007720 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08007721 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007722
Victor Stinner8c62be82010-05-06 00:08:46 +00007723 if (pid == -1)
7724 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007725
Zackery Spytz682107c2019-09-09 09:48:32 -06007726 // If wait succeeded but no child was ready to report status, ru will not
7727 // have been populated.
7728 if (pid == 0) {
7729 memset(ru, 0, sizeof(*ru));
7730 }
7731
Eddie Elizondob3966632019-11-05 07:16:14 -08007732 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7733 if (m == NULL)
7734 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02007735 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08007736 Py_DECREF(m);
7737 if (struct_rusage == NULL)
7738 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007739
Victor Stinner8c62be82010-05-06 00:08:46 +00007740 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7741 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08007742 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007743 if (!result)
7744 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007745
7746#ifndef doubletime
7747#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7748#endif
7749
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007751 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007753 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007754#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007755 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7756 SET_INT(result, 2, ru->ru_maxrss);
7757 SET_INT(result, 3, ru->ru_ixrss);
7758 SET_INT(result, 4, ru->ru_idrss);
7759 SET_INT(result, 5, ru->ru_isrss);
7760 SET_INT(result, 6, ru->ru_minflt);
7761 SET_INT(result, 7, ru->ru_majflt);
7762 SET_INT(result, 8, ru->ru_nswap);
7763 SET_INT(result, 9, ru->ru_inblock);
7764 SET_INT(result, 10, ru->ru_oublock);
7765 SET_INT(result, 11, ru->ru_msgsnd);
7766 SET_INT(result, 12, ru->ru_msgrcv);
7767 SET_INT(result, 13, ru->ru_nsignals);
7768 SET_INT(result, 14, ru->ru_nvcsw);
7769 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007770#undef SET_INT
7771
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 if (PyErr_Occurred()) {
7773 Py_DECREF(result);
7774 return NULL;
7775 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007776
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007778}
7779#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7780
Larry Hastings2f936352014-08-05 14:04:04 +10007781
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007782#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007783/*[clinic input]
7784os.wait3
7785
7786 options: int
7787Wait for completion of a child process.
7788
7789Returns a tuple of information about the child process:
7790 (pid, status, rusage)
7791[clinic start generated code]*/
7792
Larry Hastings2f936352014-08-05 14:04:04 +10007793static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007794os_wait3_impl(PyObject *module, int options)
7795/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007796{
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007799 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 WAIT_TYPE status;
7801 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007802
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007803 do {
7804 Py_BEGIN_ALLOW_THREADS
7805 pid = wait3(&status, options, &ru);
7806 Py_END_ALLOW_THREADS
7807 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7808 if (pid < 0)
7809 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007810
Victor Stinner1c2fa782020-05-10 11:05:29 +02007811 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007812}
7813#endif /* HAVE_WAIT3 */
7814
Larry Hastings2f936352014-08-05 14:04:04 +10007815
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007816#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007817/*[clinic input]
7818
7819os.wait4
7820
7821 pid: pid_t
7822 options: int
7823
7824Wait for completion of a specific child process.
7825
7826Returns a tuple of information about the child process:
7827 (pid, status, rusage)
7828[clinic start generated code]*/
7829
Larry Hastings2f936352014-08-05 14:04:04 +10007830static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007831os_wait4_impl(PyObject *module, pid_t pid, int options)
7832/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007833{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007834 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007835 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007836 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007837 WAIT_TYPE status;
7838 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007839
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007840 do {
7841 Py_BEGIN_ALLOW_THREADS
7842 res = wait4(pid, &status, options, &ru);
7843 Py_END_ALLOW_THREADS
7844 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7845 if (res < 0)
7846 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007847
Victor Stinner1c2fa782020-05-10 11:05:29 +02007848 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007849}
7850#endif /* HAVE_WAIT4 */
7851
Larry Hastings2f936352014-08-05 14:04:04 +10007852
Ross Lagerwall7807c352011-03-17 20:20:30 +02007853#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007854/*[clinic input]
7855os.waitid
7856
7857 idtype: idtype_t
7858 Must be one of be P_PID, P_PGID or P_ALL.
7859 id: id_t
7860 The id to wait on.
7861 options: int
7862 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7863 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7864 /
7865
7866Returns the result of waiting for a process or processes.
7867
7868Returns either waitid_result or None if WNOHANG is specified and there are
7869no children in a waitable state.
7870[clinic start generated code]*/
7871
Larry Hastings2f936352014-08-05 14:04:04 +10007872static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007873os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7874/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007875{
7876 PyObject *result;
7877 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007878 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007879 siginfo_t si;
7880 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007881
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007882 do {
7883 Py_BEGIN_ALLOW_THREADS
7884 res = waitid(idtype, id, &si, options);
7885 Py_END_ALLOW_THREADS
7886 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7887 if (res < 0)
7888 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007889
7890 if (si.si_pid == 0)
7891 Py_RETURN_NONE;
7892
Hai Shif707d942020-03-16 21:15:01 +08007893 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08007894 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007895 if (!result)
7896 return NULL;
7897
7898 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007899 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007900 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7901 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7902 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7903 if (PyErr_Occurred()) {
7904 Py_DECREF(result);
7905 return NULL;
7906 }
7907
7908 return result;
7909}
Larry Hastings2f936352014-08-05 14:04:04 +10007910#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007911
Larry Hastings2f936352014-08-05 14:04:04 +10007912
7913#if defined(HAVE_WAITPID)
7914/*[clinic input]
7915os.waitpid
7916 pid: pid_t
7917 options: int
7918 /
7919
7920Wait for completion of a given child process.
7921
7922Returns a tuple of information regarding the child process:
7923 (pid, status)
7924
7925The options argument is ignored on Windows.
7926[clinic start generated code]*/
7927
Larry Hastings2f936352014-08-05 14:04:04 +10007928static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007929os_waitpid_impl(PyObject *module, pid_t pid, int options)
7930/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007931{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007932 pid_t res;
7933 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 WAIT_TYPE status;
7935 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007936
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007937 do {
7938 Py_BEGIN_ALLOW_THREADS
7939 res = waitpid(pid, &status, options);
7940 Py_END_ALLOW_THREADS
7941 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7942 if (res < 0)
7943 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007944
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007945 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007946}
Tim Petersab034fa2002-02-01 11:27:43 +00007947#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007948/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007949/*[clinic input]
7950os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007951 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007952 options: int
7953 /
7954
7955Wait for completion of a given process.
7956
7957Returns a tuple of information regarding the process:
7958 (pid, status << 8)
7959
7960The options argument is ignored on Windows.
7961[clinic start generated code]*/
7962
Larry Hastings2f936352014-08-05 14:04:04 +10007963static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007964os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007965/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007966{
7967 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007968 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007969 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007970
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007971 do {
7972 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007973 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007974 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007975 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007976 Py_END_ALLOW_THREADS
7977 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007978 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007979 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007980
Victor Stinner9bee32b2020-04-22 16:30:35 +02007981 unsigned long long ustatus = (unsigned int)status;
7982
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02007984 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007985}
Larry Hastings2f936352014-08-05 14:04:04 +10007986#endif
7987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007988
Guido van Rossumad0ee831995-03-01 10:34:45 +00007989#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007990/*[clinic input]
7991os.wait
7992
7993Wait for completion of a child process.
7994
7995Returns a tuple of information about the child process:
7996 (pid, status)
7997[clinic start generated code]*/
7998
Larry Hastings2f936352014-08-05 14:04:04 +10007999static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008000os_wait_impl(PyObject *module)
8001/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008002{
Victor Stinner8c62be82010-05-06 00:08:46 +00008003 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008004 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 WAIT_TYPE status;
8006 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008007
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008008 do {
8009 Py_BEGIN_ALLOW_THREADS
8010 pid = wait(&status);
8011 Py_END_ALLOW_THREADS
8012 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8013 if (pid < 0)
8014 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008015
Victor Stinner8c62be82010-05-06 00:08:46 +00008016 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008017}
Larry Hastings2f936352014-08-05 14:04:04 +10008018#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008019
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008020#if defined(__linux__) && defined(__NR_pidfd_open)
8021/*[clinic input]
8022os.pidfd_open
8023 pid: pid_t
8024 flags: unsigned_int = 0
8025
8026Return a file descriptor referring to the process *pid*.
8027
8028The descriptor can be used to perform process management without races and
8029signals.
8030[clinic start generated code]*/
8031
8032static PyObject *
8033os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8034/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8035{
8036 int fd = syscall(__NR_pidfd_open, pid, flags);
8037 if (fd < 0) {
8038 return posix_error();
8039 }
8040 return PyLong_FromLong(fd);
8041}
8042#endif
8043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008044
Larry Hastings9cf065c2012-06-22 16:30:09 -07008045#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008046/*[clinic input]
8047os.readlink
8048
8049 path: path_t
8050 *
8051 dir_fd: dir_fd(requires='readlinkat') = None
8052
8053Return a string representing the path to which the symbolic link points.
8054
8055If dir_fd is not None, it should be a file descriptor open to a directory,
8056and path should be relative; path will then be relative to that directory.
8057
8058dir_fd may not be implemented on your platform. If it is unavailable,
8059using it will raise a NotImplementedError.
8060[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008061
Barry Warsaw53699e91996-12-10 23:23:01 +00008062static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008063os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8064/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008065{
Berker Peksage0b5b202018-08-15 13:03:41 +03008066#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008067 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008068 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008069
8070 Py_BEGIN_ALLOW_THREADS
8071#ifdef HAVE_READLINKAT
8072 if (dir_fd != DEFAULT_DIR_FD)
8073 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8074 else
8075#endif
8076 length = readlink(path->narrow, buffer, MAXPATHLEN);
8077 Py_END_ALLOW_THREADS
8078
8079 if (length < 0) {
8080 return path_error(path);
8081 }
8082 buffer[length] = '\0';
8083
8084 if (PyUnicode_Check(path->object))
8085 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8086 else
8087 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008088#elif defined(MS_WINDOWS)
8089 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008090 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008091 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008092 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8093 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008094 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008095
Larry Hastings2f936352014-08-05 14:04:04 +10008096 /* First get a handle to the reparse point */
8097 Py_BEGIN_ALLOW_THREADS
8098 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008099 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008100 0,
8101 0,
8102 0,
8103 OPEN_EXISTING,
8104 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8105 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008106 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8107 /* New call DeviceIoControl to read the reparse point */
8108 io_result = DeviceIoControl(
8109 reparse_point_handle,
8110 FSCTL_GET_REPARSE_POINT,
8111 0, 0, /* in buffer */
8112 target_buffer, sizeof(target_buffer),
8113 &n_bytes_returned,
8114 0 /* we're not using OVERLAPPED_IO */
8115 );
8116 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008117 }
Larry Hastings2f936352014-08-05 14:04:04 +10008118 Py_END_ALLOW_THREADS
8119
Berker Peksage0b5b202018-08-15 13:03:41 +03008120 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008121 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008122 }
Larry Hastings2f936352014-08-05 14:04:04 +10008123
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008124 wchar_t *name = NULL;
8125 Py_ssize_t nameLen = 0;
8126 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008127 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008128 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8129 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8130 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008131 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008132 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8133 {
8134 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8135 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8136 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8137 }
8138 else
8139 {
8140 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8141 }
8142 if (name) {
8143 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8144 /* Our buffer is mutable, so this is okay */
8145 name[1] = L'\\';
8146 }
8147 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008148 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008149 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8150 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008151 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008152 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008153#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008154}
Berker Peksage0b5b202018-08-15 13:03:41 +03008155#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008156
Larry Hastings9cf065c2012-06-22 16:30:09 -07008157#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07008158
8159#if defined(MS_WINDOWS)
8160
Steve Dower6921e732018-03-05 14:26:08 -08008161/* Remove the last portion of the path - return 0 on success */
8162static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008163_dirnameW(WCHAR *path)
8164{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008165 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008166 size_t length = wcsnlen_s(path, MAX_PATH);
8167 if (length == MAX_PATH) {
8168 return -1;
8169 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008170
8171 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008172 for(ptr = path + length; ptr != path; ptr--) {
8173 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008174 break;
Steve Dower6921e732018-03-05 14:26:08 -08008175 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008176 }
8177 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008178 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008179}
8180
Victor Stinner31b3b922013-06-05 01:49:17 +02008181/* Is this path absolute? */
8182static int
8183_is_absW(const WCHAR *path)
8184{
Steve Dower6921e732018-03-05 14:26:08 -08008185 return path[0] == L'\\' || path[0] == L'/' ||
8186 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008187}
8188
Steve Dower6921e732018-03-05 14:26:08 -08008189/* join root and rest with a backslash - return 0 on success */
8190static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008191_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8192{
Victor Stinner31b3b922013-06-05 01:49:17 +02008193 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008194 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008195 }
8196
Steve Dower6921e732018-03-05 14:26:08 -08008197 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8198 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008199 }
Steve Dower6921e732018-03-05 14:26:08 -08008200
8201 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8202 return -1;
8203 }
8204
8205 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008206}
8207
Victor Stinner31b3b922013-06-05 01:49:17 +02008208/* Return True if the path at src relative to dest is a directory */
8209static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008210_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008211{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008212 WIN32_FILE_ATTRIBUTE_DATA src_info;
8213 WCHAR dest_parent[MAX_PATH];
8214 WCHAR src_resolved[MAX_PATH] = L"";
8215
8216 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008217 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8218 _dirnameW(dest_parent)) {
8219 return 0;
8220 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008221 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008222 if (_joinW(src_resolved, dest_parent, src)) {
8223 return 0;
8224 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008225 return (
8226 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8227 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8228 );
8229}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008230#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008231
Larry Hastings2f936352014-08-05 14:04:04 +10008232
8233/*[clinic input]
8234os.symlink
8235 src: path_t
8236 dst: path_t
8237 target_is_directory: bool = False
8238 *
8239 dir_fd: dir_fd(requires='symlinkat')=None
8240
8241# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8242
8243Create a symbolic link pointing to src named dst.
8244
8245target_is_directory is required on Windows if the target is to be
8246 interpreted as a directory. (On Windows, symlink requires
8247 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8248 target_is_directory is ignored on non-Windows platforms.
8249
8250If dir_fd is not None, it should be a file descriptor open to a directory,
8251 and path should be relative; path will then be relative to that directory.
8252dir_fd may not be implemented on your platform.
8253 If it is unavailable, using it will raise a NotImplementedError.
8254
8255[clinic start generated code]*/
8256
Larry Hastings2f936352014-08-05 14:04:04 +10008257static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008258os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008259 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008260/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008261{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008262#ifdef MS_WINDOWS
8263 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008264 DWORD flags = 0;
8265
8266 /* Assumed true, set to false if detected to not be available. */
8267 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008268#else
8269 int result;
8270#endif
8271
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008272 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8273 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8274 return NULL;
8275 }
8276
Larry Hastings9cf065c2012-06-22 16:30:09 -07008277#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008278
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008279 if (windows_has_symlink_unprivileged_flag) {
8280 /* Allow non-admin symlinks if system allows it. */
8281 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8282 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008283
Larry Hastings9cf065c2012-06-22 16:30:09 -07008284 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008285 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008286 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8287 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8288 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8289 }
8290
8291 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008292 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008293 Py_END_ALLOW_THREADS
8294
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008295 if (windows_has_symlink_unprivileged_flag && !result &&
8296 ERROR_INVALID_PARAMETER == GetLastError()) {
8297
8298 Py_BEGIN_ALLOW_THREADS
8299 _Py_BEGIN_SUPPRESS_IPH
8300 /* This error might be caused by
8301 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8302 Try again, and update windows_has_symlink_unprivileged_flag if we
8303 are successful this time.
8304
8305 NOTE: There is a risk of a race condition here if there are other
8306 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8307 another process (or thread) changes that condition in between our
8308 calls to CreateSymbolicLink.
8309 */
8310 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8311 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8312 _Py_END_SUPPRESS_IPH
8313 Py_END_ALLOW_THREADS
8314
8315 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8316 windows_has_symlink_unprivileged_flag = FALSE;
8317 }
8318 }
8319
Larry Hastings2f936352014-08-05 14:04:04 +10008320 if (!result)
8321 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008322
8323#else
8324
Steve Dower6921e732018-03-05 14:26:08 -08008325 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8326 PyErr_SetString(PyExc_ValueError,
8327 "symlink: src and dst must be the same type");
8328 return NULL;
8329 }
8330
Larry Hastings9cf065c2012-06-22 16:30:09 -07008331 Py_BEGIN_ALLOW_THREADS
8332#if HAVE_SYMLINKAT
8333 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008334 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008335 else
8336#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008337 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008338 Py_END_ALLOW_THREADS
8339
Larry Hastings2f936352014-08-05 14:04:04 +10008340 if (result)
8341 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008342#endif
8343
Larry Hastings2f936352014-08-05 14:04:04 +10008344 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008345}
8346#endif /* HAVE_SYMLINK */
8347
Larry Hastings9cf065c2012-06-22 16:30:09 -07008348
Brian Curtind40e6f72010-07-08 21:39:08 +00008349
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008350
Larry Hastings605a62d2012-06-24 04:33:36 -07008351static PyStructSequence_Field times_result_fields[] = {
8352 {"user", "user time"},
8353 {"system", "system time"},
8354 {"children_user", "user time of children"},
8355 {"children_system", "system time of children"},
8356 {"elapsed", "elapsed time since an arbitrary point in the past"},
8357 {NULL}
8358};
8359
8360PyDoc_STRVAR(times_result__doc__,
8361"times_result: Result from os.times().\n\n\
8362This object may be accessed either as a tuple of\n\
8363 (user, system, children_user, children_system, elapsed),\n\
8364or via the attributes user, system, children_user, children_system,\n\
8365and elapsed.\n\
8366\n\
8367See os.times for more information.");
8368
8369static PyStructSequence_Desc times_result_desc = {
8370 "times_result", /* name */
8371 times_result__doc__, /* doc */
8372 times_result_fields,
8373 5
8374};
8375
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008376#ifdef MS_WINDOWS
8377#define HAVE_TIMES /* mandatory, for the method table */
8378#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008379
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008380#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008381
8382static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008383build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008384 double children_user, double children_system,
8385 double elapsed)
8386{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008387 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008388 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008389 if (value == NULL)
8390 return NULL;
8391
8392#define SET(i, field) \
8393 { \
8394 PyObject *o = PyFloat_FromDouble(field); \
8395 if (!o) { \
8396 Py_DECREF(value); \
8397 return NULL; \
8398 } \
8399 PyStructSequence_SET_ITEM(value, i, o); \
8400 } \
8401
8402 SET(0, user);
8403 SET(1, system);
8404 SET(2, children_user);
8405 SET(3, children_system);
8406 SET(4, elapsed);
8407
8408#undef SET
8409
8410 return value;
8411}
8412
Larry Hastings605a62d2012-06-24 04:33:36 -07008413
Larry Hastings2f936352014-08-05 14:04:04 +10008414#ifndef MS_WINDOWS
8415#define NEED_TICKS_PER_SECOND
8416static long ticks_per_second = -1;
8417#endif /* MS_WINDOWS */
8418
8419/*[clinic input]
8420os.times
8421
8422Return a collection containing process timing information.
8423
8424The object returned behaves like a named tuple with these fields:
8425 (utime, stime, cutime, cstime, elapsed_time)
8426All fields are floating point numbers.
8427[clinic start generated code]*/
8428
Larry Hastings2f936352014-08-05 14:04:04 +10008429static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008430os_times_impl(PyObject *module)
8431/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008432#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008433{
Victor Stinner8c62be82010-05-06 00:08:46 +00008434 FILETIME create, exit, kernel, user;
8435 HANDLE hProc;
8436 hProc = GetCurrentProcess();
8437 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8438 /* The fields of a FILETIME structure are the hi and lo part
8439 of a 64-bit value expressed in 100 nanosecond units.
8440 1e7 is one second in such units; 1e-7 the inverse.
8441 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8442 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008443 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008444 (double)(user.dwHighDateTime*429.4967296 +
8445 user.dwLowDateTime*1e-7),
8446 (double)(kernel.dwHighDateTime*429.4967296 +
8447 kernel.dwLowDateTime*1e-7),
8448 (double)0,
8449 (double)0,
8450 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008451}
Larry Hastings2f936352014-08-05 14:04:04 +10008452#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008453{
Larry Hastings2f936352014-08-05 14:04:04 +10008454
8455
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008456 struct tms t;
8457 clock_t c;
8458 errno = 0;
8459 c = times(&t);
8460 if (c == (clock_t) -1)
8461 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008462 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008463 (double)t.tms_utime / ticks_per_second,
8464 (double)t.tms_stime / ticks_per_second,
8465 (double)t.tms_cutime / ticks_per_second,
8466 (double)t.tms_cstime / ticks_per_second,
8467 (double)c / ticks_per_second);
8468}
Larry Hastings2f936352014-08-05 14:04:04 +10008469#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008470#endif /* HAVE_TIMES */
8471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008472
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008473#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008474/*[clinic input]
8475os.getsid
8476
8477 pid: pid_t
8478 /
8479
8480Call the system call getsid(pid) and return the result.
8481[clinic start generated code]*/
8482
Larry Hastings2f936352014-08-05 14:04:04 +10008483static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008484os_getsid_impl(PyObject *module, pid_t pid)
8485/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008486{
Victor Stinner8c62be82010-05-06 00:08:46 +00008487 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008488 sid = getsid(pid);
8489 if (sid < 0)
8490 return posix_error();
8491 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008492}
8493#endif /* HAVE_GETSID */
8494
8495
Guido van Rossumb6775db1994-08-01 11:34:53 +00008496#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008497/*[clinic input]
8498os.setsid
8499
8500Call the system call setsid().
8501[clinic start generated code]*/
8502
Larry Hastings2f936352014-08-05 14:04:04 +10008503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008504os_setsid_impl(PyObject *module)
8505/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008506{
Victor Stinner8c62be82010-05-06 00:08:46 +00008507 if (setsid() < 0)
8508 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008509 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008510}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008511#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008512
Larry Hastings2f936352014-08-05 14:04:04 +10008513
Guido van Rossumb6775db1994-08-01 11:34:53 +00008514#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008515/*[clinic input]
8516os.setpgid
8517
8518 pid: pid_t
8519 pgrp: pid_t
8520 /
8521
8522Call the system call setpgid(pid, pgrp).
8523[clinic start generated code]*/
8524
Larry Hastings2f936352014-08-05 14:04:04 +10008525static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008526os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8527/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008528{
Victor Stinner8c62be82010-05-06 00:08:46 +00008529 if (setpgid(pid, pgrp) < 0)
8530 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008531 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008532}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008533#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008534
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008535
Guido van Rossumb6775db1994-08-01 11:34:53 +00008536#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008537/*[clinic input]
8538os.tcgetpgrp
8539
8540 fd: int
8541 /
8542
8543Return the process group associated with the terminal specified by fd.
8544[clinic start generated code]*/
8545
Larry Hastings2f936352014-08-05 14:04:04 +10008546static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008547os_tcgetpgrp_impl(PyObject *module, int fd)
8548/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008549{
8550 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008551 if (pgid < 0)
8552 return posix_error();
8553 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008554}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008555#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008556
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008557
Guido van Rossumb6775db1994-08-01 11:34:53 +00008558#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008559/*[clinic input]
8560os.tcsetpgrp
8561
8562 fd: int
8563 pgid: pid_t
8564 /
8565
8566Set the process group associated with the terminal specified by fd.
8567[clinic start generated code]*/
8568
Larry Hastings2f936352014-08-05 14:04:04 +10008569static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008570os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8571/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008572{
Victor Stinner8c62be82010-05-06 00:08:46 +00008573 if (tcsetpgrp(fd, pgid) < 0)
8574 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008575 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008576}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008577#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008578
Guido van Rossum687dd131993-05-17 08:34:16 +00008579/* Functions acting on file descriptors */
8580
Victor Stinnerdaf45552013-08-28 00:53:59 +02008581#ifdef O_CLOEXEC
8582extern int _Py_open_cloexec_works;
8583#endif
8584
Larry Hastings2f936352014-08-05 14:04:04 +10008585
8586/*[clinic input]
8587os.open -> int
8588 path: path_t
8589 flags: int
8590 mode: int = 0o777
8591 *
8592 dir_fd: dir_fd(requires='openat') = None
8593
8594# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8595
8596Open a file for low level IO. Returns a file descriptor (integer).
8597
8598If dir_fd is not None, it should be a file descriptor open to a directory,
8599 and path should be relative; path will then be relative to that directory.
8600dir_fd may not be implemented on your platform.
8601 If it is unavailable, using it will raise a NotImplementedError.
8602[clinic start generated code]*/
8603
Larry Hastings2f936352014-08-05 14:04:04 +10008604static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008605os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8606/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008607{
8608 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008609 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008610
Victor Stinnerdaf45552013-08-28 00:53:59 +02008611#ifdef O_CLOEXEC
8612 int *atomic_flag_works = &_Py_open_cloexec_works;
8613#elif !defined(MS_WINDOWS)
8614 int *atomic_flag_works = NULL;
8615#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008616
Victor Stinnerdaf45552013-08-28 00:53:59 +02008617#ifdef MS_WINDOWS
8618 flags |= O_NOINHERIT;
8619#elif defined(O_CLOEXEC)
8620 flags |= O_CLOEXEC;
8621#endif
8622
Steve Dowerb82e17e2019-05-23 08:45:22 -07008623 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8624 return -1;
8625 }
8626
Steve Dower8fc89802015-04-12 00:26:27 -04008627 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008628 do {
8629 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008630#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008631 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008632#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008633#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008634 if (dir_fd != DEFAULT_DIR_FD)
8635 fd = openat(dir_fd, path->narrow, flags, mode);
8636 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008637#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008638 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008639#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008640 Py_END_ALLOW_THREADS
8641 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008642 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008643
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008644 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008645 if (!async_err)
8646 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008647 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008648 }
8649
Victor Stinnerdaf45552013-08-28 00:53:59 +02008650#ifndef MS_WINDOWS
8651 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8652 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008653 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008654 }
8655#endif
8656
Larry Hastings2f936352014-08-05 14:04:04 +10008657 return fd;
8658}
8659
8660
8661/*[clinic input]
8662os.close
8663
8664 fd: int
8665
8666Close a file descriptor.
8667[clinic start generated code]*/
8668
Barry Warsaw53699e91996-12-10 23:23:01 +00008669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008670os_close_impl(PyObject *module, int fd)
8671/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008672{
Larry Hastings2f936352014-08-05 14:04:04 +10008673 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008674 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8675 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8676 * for more details.
8677 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008678 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008679 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008680 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008681 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008682 Py_END_ALLOW_THREADS
8683 if (res < 0)
8684 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008685 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008686}
8687
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008688
Jakub Kulíke20134f2019-09-11 17:11:57 +02008689#ifdef HAVE_FDWALK
8690static int
8691_fdwalk_close_func(void *lohi, int fd)
8692{
8693 int lo = ((int *)lohi)[0];
8694 int hi = ((int *)lohi)[1];
8695
Victor Stinner162c5672020-04-24 12:00:51 +02008696 if (fd >= hi) {
Jakub Kulíke20134f2019-09-11 17:11:57 +02008697 return 1;
Victor Stinner162c5672020-04-24 12:00:51 +02008698 }
8699 else if (fd >= lo) {
8700 /* Ignore errors */
8701 (void)close(fd);
8702 }
Jakub Kulíke20134f2019-09-11 17:11:57 +02008703 return 0;
8704}
8705#endif /* HAVE_FDWALK */
8706
Larry Hastings2f936352014-08-05 14:04:04 +10008707/*[clinic input]
8708os.closerange
8709
8710 fd_low: int
8711 fd_high: int
8712 /
8713
8714Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8715[clinic start generated code]*/
8716
Larry Hastings2f936352014-08-05 14:04:04 +10008717static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008718os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8719/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008720{
Jakub Kulíke20134f2019-09-11 17:11:57 +02008721#ifdef HAVE_FDWALK
8722 int lohi[2];
Jakub Kulíke20134f2019-09-11 17:11:57 +02008723#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008724 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008725 _Py_BEGIN_SUPPRESS_IPH
Jakub Kulíke20134f2019-09-11 17:11:57 +02008726#ifdef HAVE_FDWALK
8727 lohi[0] = Py_MAX(fd_low, 0);
8728 lohi[1] = fd_high;
8729 fdwalk(_fdwalk_close_func, lohi);
8730#else
Victor Stinner162c5672020-04-24 12:00:51 +02008731 fd_low = Py_MAX(fd_low, 0);
8732#ifdef __FreeBSD__
8733 if (fd_high >= sysconf(_SC_OPEN_MAX)) {
8734 /* Any errors encountered while closing file descriptors are ignored */
8735 closefrom(fd_low);
8736 }
8737 else
8738#endif
8739 {
8740 for (int i = fd_low; i < fd_high; i++) {
8741 /* Ignore errors */
8742 (void)close(i);
8743 }
8744 }
Jakub Kulíke20134f2019-09-11 17:11:57 +02008745#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008746 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008747 Py_END_ALLOW_THREADS
8748 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008749}
8750
8751
Larry Hastings2f936352014-08-05 14:04:04 +10008752/*[clinic input]
8753os.dup -> int
8754
8755 fd: int
8756 /
8757
8758Return a duplicate of a file descriptor.
8759[clinic start generated code]*/
8760
Larry Hastings2f936352014-08-05 14:04:04 +10008761static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008762os_dup_impl(PyObject *module, int fd)
8763/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008764{
8765 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008766}
8767
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008768
Larry Hastings2f936352014-08-05 14:04:04 +10008769/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008770os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008771 fd: int
8772 fd2: int
8773 inheritable: bool=True
8774
8775Duplicate file descriptor.
8776[clinic start generated code]*/
8777
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008778static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008779os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008780/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008781{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008782 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008783#if defined(HAVE_DUP3) && \
8784 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8785 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008786 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008787#endif
8788
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008789 if (fd < 0 || fd2 < 0) {
8790 posix_error();
8791 return -1;
8792 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008793
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008794 /* dup2() can fail with EINTR if the target FD is already open, because it
8795 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8796 * upon close(), and therefore below.
8797 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008798#ifdef MS_WINDOWS
8799 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008800 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008801 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008802 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008803 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008804 if (res < 0) {
8805 posix_error();
8806 return -1;
8807 }
8808 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008809
8810 /* Character files like console cannot be make non-inheritable */
8811 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8812 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008813 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008814 }
8815
8816#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8817 Py_BEGIN_ALLOW_THREADS
8818 if (!inheritable)
8819 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8820 else
8821 res = dup2(fd, fd2);
8822 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008823 if (res < 0) {
8824 posix_error();
8825 return -1;
8826 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008827
8828#else
8829
8830#ifdef HAVE_DUP3
8831 if (!inheritable && dup3_works != 0) {
8832 Py_BEGIN_ALLOW_THREADS
8833 res = dup3(fd, fd2, O_CLOEXEC);
8834 Py_END_ALLOW_THREADS
8835 if (res < 0) {
8836 if (dup3_works == -1)
8837 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008838 if (dup3_works) {
8839 posix_error();
8840 return -1;
8841 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008842 }
8843 }
8844
8845 if (inheritable || dup3_works == 0)
8846 {
8847#endif
8848 Py_BEGIN_ALLOW_THREADS
8849 res = dup2(fd, fd2);
8850 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008851 if (res < 0) {
8852 posix_error();
8853 return -1;
8854 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008855
8856 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8857 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008858 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008859 }
8860#ifdef HAVE_DUP3
8861 }
8862#endif
8863
8864#endif
8865
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008866 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008867}
8868
Larry Hastings2f936352014-08-05 14:04:04 +10008869
Ross Lagerwall7807c352011-03-17 20:20:30 +02008870#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008871/*[clinic input]
8872os.lockf
8873
8874 fd: int
8875 An open file descriptor.
8876 command: int
8877 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8878 length: Py_off_t
8879 The number of bytes to lock, starting at the current position.
8880 /
8881
8882Apply, test or remove a POSIX lock on an open file descriptor.
8883
8884[clinic start generated code]*/
8885
Larry Hastings2f936352014-08-05 14:04:04 +10008886static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008887os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8888/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008889{
8890 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008891
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008892 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
8893 return NULL;
8894 }
8895
Ross Lagerwall7807c352011-03-17 20:20:30 +02008896 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008897 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008898 Py_END_ALLOW_THREADS
8899
8900 if (res < 0)
8901 return posix_error();
8902
8903 Py_RETURN_NONE;
8904}
Larry Hastings2f936352014-08-05 14:04:04 +10008905#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008906
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008907
Larry Hastings2f936352014-08-05 14:04:04 +10008908/*[clinic input]
8909os.lseek -> Py_off_t
8910
8911 fd: int
8912 position: Py_off_t
8913 how: int
8914 /
8915
8916Set the position of a file descriptor. Return the new position.
8917
8918Return the new cursor position in number of bytes
8919relative to the beginning of the file.
8920[clinic start generated code]*/
8921
Larry Hastings2f936352014-08-05 14:04:04 +10008922static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008923os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8924/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008925{
8926 Py_off_t result;
8927
Guido van Rossum687dd131993-05-17 08:34:16 +00008928#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008929 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8930 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008931 case 0: how = SEEK_SET; break;
8932 case 1: how = SEEK_CUR; break;
8933 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008934 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008935#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008936
Victor Stinner8c62be82010-05-06 00:08:46 +00008937 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008938 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008939#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008940 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008941#else
Larry Hastings2f936352014-08-05 14:04:04 +10008942 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008943#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008944 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008946 if (result < 0)
8947 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008948
Larry Hastings2f936352014-08-05 14:04:04 +10008949 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008950}
8951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008952
Larry Hastings2f936352014-08-05 14:04:04 +10008953/*[clinic input]
8954os.read
8955 fd: int
8956 length: Py_ssize_t
8957 /
8958
8959Read from a file descriptor. Returns a bytes object.
8960[clinic start generated code]*/
8961
Larry Hastings2f936352014-08-05 14:04:04 +10008962static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008963os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8964/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008965{
Victor Stinner8c62be82010-05-06 00:08:46 +00008966 Py_ssize_t n;
8967 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008968
8969 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008970 errno = EINVAL;
8971 return posix_error();
8972 }
Larry Hastings2f936352014-08-05 14:04:04 +10008973
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008974 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008975
8976 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008977 if (buffer == NULL)
8978 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008979
Victor Stinner66aab0c2015-03-19 22:53:20 +01008980 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8981 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008982 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008983 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008984 }
Larry Hastings2f936352014-08-05 14:04:04 +10008985
8986 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008987 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008988
Victor Stinner8c62be82010-05-06 00:08:46 +00008989 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008990}
8991
Ross Lagerwall7807c352011-03-17 20:20:30 +02008992#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008993 || defined(__APPLE__))) \
8994 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8995 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8996static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008997iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008998{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008999 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009000
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009001 *iov = PyMem_New(struct iovec, cnt);
9002 if (*iov == NULL) {
9003 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009004 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009005 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009006
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009007 *buf = PyMem_New(Py_buffer, cnt);
9008 if (*buf == NULL) {
9009 PyMem_Del(*iov);
9010 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009011 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009012 }
9013
9014 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009015 PyObject *item = PySequence_GetItem(seq, i);
9016 if (item == NULL)
9017 goto fail;
9018 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9019 Py_DECREF(item);
9020 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009021 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009022 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009023 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009024 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009025 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009026 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009027
9028fail:
9029 PyMem_Del(*iov);
9030 for (j = 0; j < i; j++) {
9031 PyBuffer_Release(&(*buf)[j]);
9032 }
9033 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009034 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009035}
9036
9037static void
9038iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9039{
9040 int i;
9041 PyMem_Del(iov);
9042 for (i = 0; i < cnt; i++) {
9043 PyBuffer_Release(&buf[i]);
9044 }
9045 PyMem_Del(buf);
9046}
9047#endif
9048
Larry Hastings2f936352014-08-05 14:04:04 +10009049
Ross Lagerwall7807c352011-03-17 20:20:30 +02009050#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009051/*[clinic input]
9052os.readv -> Py_ssize_t
9053
9054 fd: int
9055 buffers: object
9056 /
9057
9058Read from a file descriptor fd into an iterable of buffers.
9059
9060The buffers should be mutable buffers accepting bytes.
9061readv will transfer data into each buffer until it is full
9062and then move on to the next buffer in the sequence to hold
9063the rest of the data.
9064
9065readv returns the total number of bytes read,
9066which may be less than the total capacity of all the buffers.
9067[clinic start generated code]*/
9068
Larry Hastings2f936352014-08-05 14:04:04 +10009069static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009070os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9071/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009072{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009073 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009074 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009075 struct iovec *iov;
9076 Py_buffer *buf;
9077
Larry Hastings2f936352014-08-05 14:04:04 +10009078 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009079 PyErr_SetString(PyExc_TypeError,
9080 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009081 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009082 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009083
Larry Hastings2f936352014-08-05 14:04:04 +10009084 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009085 if (cnt < 0)
9086 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009087
9088 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9089 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009090
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009091 do {
9092 Py_BEGIN_ALLOW_THREADS
9093 n = readv(fd, iov, cnt);
9094 Py_END_ALLOW_THREADS
9095 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009096
9097 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009098 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009099 if (!async_err)
9100 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009101 return -1;
9102 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009103
Larry Hastings2f936352014-08-05 14:04:04 +10009104 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009105}
Larry Hastings2f936352014-08-05 14:04:04 +10009106#endif /* HAVE_READV */
9107
Ross Lagerwall7807c352011-03-17 20:20:30 +02009108
9109#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009110/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009111os.pread
9112
9113 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009114 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009115 offset: Py_off_t
9116 /
9117
9118Read a number of bytes from a file descriptor starting at a particular offset.
9119
9120Read length bytes from file descriptor fd, starting at offset bytes from
9121the beginning of the file. The file offset remains unchanged.
9122[clinic start generated code]*/
9123
Larry Hastings2f936352014-08-05 14:04:04 +10009124static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009125os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9126/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009127{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009128 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009129 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009130 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009131
Larry Hastings2f936352014-08-05 14:04:04 +10009132 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009133 errno = EINVAL;
9134 return posix_error();
9135 }
Larry Hastings2f936352014-08-05 14:04:04 +10009136 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009137 if (buffer == NULL)
9138 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009139
9140 do {
9141 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009142 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009143 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009144 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009145 Py_END_ALLOW_THREADS
9146 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9147
Ross Lagerwall7807c352011-03-17 20:20:30 +02009148 if (n < 0) {
9149 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009150 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009151 }
Larry Hastings2f936352014-08-05 14:04:04 +10009152 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009153 _PyBytes_Resize(&buffer, n);
9154 return buffer;
9155}
Larry Hastings2f936352014-08-05 14:04:04 +10009156#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009157
Pablo Galindo4defba32018-01-27 16:16:37 +00009158#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9159/*[clinic input]
9160os.preadv -> Py_ssize_t
9161
9162 fd: int
9163 buffers: object
9164 offset: Py_off_t
9165 flags: int = 0
9166 /
9167
9168Reads from a file descriptor into a number of mutable bytes-like objects.
9169
9170Combines the functionality of readv() and pread(). As readv(), it will
9171transfer data into each buffer until it is full and then move on to the next
9172buffer in the sequence to hold the rest of the data. Its fourth argument,
9173specifies the file offset at which the input operation is to be performed. It
9174will return the total number of bytes read (which can be less than the total
9175capacity of all the objects).
9176
9177The flags argument contains a bitwise OR of zero or more of the following flags:
9178
9179- RWF_HIPRI
9180- RWF_NOWAIT
9181
9182Using non-zero flags requires Linux 4.6 or newer.
9183[clinic start generated code]*/
9184
9185static Py_ssize_t
9186os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9187 int flags)
9188/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9189{
9190 Py_ssize_t cnt, n;
9191 int async_err = 0;
9192 struct iovec *iov;
9193 Py_buffer *buf;
9194
9195 if (!PySequence_Check(buffers)) {
9196 PyErr_SetString(PyExc_TypeError,
9197 "preadv2() arg 2 must be a sequence");
9198 return -1;
9199 }
9200
9201 cnt = PySequence_Size(buffers);
9202 if (cnt < 0) {
9203 return -1;
9204 }
9205
9206#ifndef HAVE_PREADV2
9207 if(flags != 0) {
9208 argument_unavailable_error("preadv2", "flags");
9209 return -1;
9210 }
9211#endif
9212
9213 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9214 return -1;
9215 }
9216#ifdef HAVE_PREADV2
9217 do {
9218 Py_BEGIN_ALLOW_THREADS
9219 _Py_BEGIN_SUPPRESS_IPH
9220 n = preadv2(fd, iov, cnt, offset, flags);
9221 _Py_END_SUPPRESS_IPH
9222 Py_END_ALLOW_THREADS
9223 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9224#else
9225 do {
9226 Py_BEGIN_ALLOW_THREADS
9227 _Py_BEGIN_SUPPRESS_IPH
9228 n = preadv(fd, iov, cnt, offset);
9229 _Py_END_SUPPRESS_IPH
9230 Py_END_ALLOW_THREADS
9231 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9232#endif
9233
9234 iov_cleanup(iov, buf, cnt);
9235 if (n < 0) {
9236 if (!async_err) {
9237 posix_error();
9238 }
9239 return -1;
9240 }
9241
9242 return n;
9243}
9244#endif /* HAVE_PREADV */
9245
Larry Hastings2f936352014-08-05 14:04:04 +10009246
9247/*[clinic input]
9248os.write -> Py_ssize_t
9249
9250 fd: int
9251 data: Py_buffer
9252 /
9253
9254Write a bytes object to a file descriptor.
9255[clinic start generated code]*/
9256
Larry Hastings2f936352014-08-05 14:04:04 +10009257static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009258os_write_impl(PyObject *module, int fd, Py_buffer *data)
9259/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009260{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009261 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009262}
9263
9264#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009265#ifdef __APPLE__
9266/*[clinic input]
9267os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009268
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009269 out_fd: int
9270 in_fd: int
9271 offset: Py_off_t
9272 count as sbytes: Py_off_t
9273 headers: object(c_default="NULL") = ()
9274 trailers: object(c_default="NULL") = ()
9275 flags: int = 0
9276
9277Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9278[clinic start generated code]*/
9279
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009280static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009281os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9282 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9283 int flags)
9284/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9285#elif defined(__FreeBSD__) || defined(__DragonFly__)
9286/*[clinic input]
9287os.sendfile
9288
9289 out_fd: int
9290 in_fd: int
9291 offset: Py_off_t
9292 count: Py_ssize_t
9293 headers: object(c_default="NULL") = ()
9294 trailers: object(c_default="NULL") = ()
9295 flags: int = 0
9296
9297Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9298[clinic start generated code]*/
9299
9300static PyObject *
9301os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9302 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9303 int flags)
9304/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9305#else
9306/*[clinic input]
9307os.sendfile
9308
9309 out_fd: int
9310 in_fd: int
9311 offset as offobj: object
9312 count: Py_ssize_t
9313
9314Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9315[clinic start generated code]*/
9316
9317static PyObject *
9318os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9319 Py_ssize_t count)
9320/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9321#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009322{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009323 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009324 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009325
9326#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9327#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009328 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009329#endif
9330 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009331 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009332
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009333 sf.headers = NULL;
9334 sf.trailers = NULL;
9335
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009336 if (headers != NULL) {
9337 if (!PySequence_Check(headers)) {
9338 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009339 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009340 return NULL;
9341 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009342 Py_ssize_t i = PySequence_Size(headers);
9343 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009344 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009345 if (i > INT_MAX) {
9346 PyErr_SetString(PyExc_OverflowError,
9347 "sendfile() header is too large");
9348 return NULL;
9349 }
9350 if (i > 0) {
9351 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009352 if (iov_setup(&(sf.headers), &hbuf,
9353 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009354 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009355#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009356 for (i = 0; i < sf.hdr_cnt; i++) {
9357 Py_ssize_t blen = sf.headers[i].iov_len;
9358# define OFF_T_MAX 0x7fffffffffffffff
9359 if (sbytes >= OFF_T_MAX - blen) {
9360 PyErr_SetString(PyExc_OverflowError,
9361 "sendfile() header is too large");
9362 return NULL;
9363 }
9364 sbytes += blen;
9365 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009366#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009367 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009368 }
9369 }
9370 if (trailers != NULL) {
9371 if (!PySequence_Check(trailers)) {
9372 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009373 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009374 return NULL;
9375 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009376 Py_ssize_t i = PySequence_Size(trailers);
9377 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009378 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009379 if (i > INT_MAX) {
9380 PyErr_SetString(PyExc_OverflowError,
9381 "sendfile() trailer is too large");
9382 return NULL;
9383 }
9384 if (i > 0) {
9385 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009386 if (iov_setup(&(sf.trailers), &tbuf,
9387 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009388 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009389 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009390 }
9391 }
9392
Steve Dower8fc89802015-04-12 00:26:27 -04009393 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009394 do {
9395 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009396#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009397 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009398#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009399 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009400#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009401 Py_END_ALLOW_THREADS
9402 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009403 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009404
9405 if (sf.headers != NULL)
9406 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9407 if (sf.trailers != NULL)
9408 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9409
9410 if (ret < 0) {
9411 if ((errno == EAGAIN) || (errno == EBUSY)) {
9412 if (sbytes != 0) {
9413 // some data has been sent
9414 goto done;
9415 }
9416 else {
9417 // no data has been sent; upper application is supposed
9418 // to retry on EAGAIN or EBUSY
9419 return posix_error();
9420 }
9421 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009422 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009423 }
9424 goto done;
9425
9426done:
9427 #if !defined(HAVE_LARGEFILE_SUPPORT)
9428 return Py_BuildValue("l", sbytes);
9429 #else
9430 return Py_BuildValue("L", sbytes);
9431 #endif
9432
9433#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009434#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009435 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009436 do {
9437 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009438 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009439 Py_END_ALLOW_THREADS
9440 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009441 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009442 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009443 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009444 }
9445#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009446 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009447 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009448 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009449
9450 do {
9451 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009452 ret = sendfile(out_fd, in_fd, &offset, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009453 Py_END_ALLOW_THREADS
9454 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009455 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009456 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009457 return Py_BuildValue("n", ret);
9458#endif
9459}
Larry Hastings2f936352014-08-05 14:04:04 +10009460#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009461
Larry Hastings2f936352014-08-05 14:04:04 +10009462
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009463#if defined(__APPLE__)
9464/*[clinic input]
9465os._fcopyfile
9466
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009467 in_fd: int
9468 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009469 flags: int
9470 /
9471
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009472Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009473[clinic start generated code]*/
9474
9475static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009476os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9477/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009478{
9479 int ret;
9480
9481 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009482 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009483 Py_END_ALLOW_THREADS
9484 if (ret < 0)
9485 return posix_error();
9486 Py_RETURN_NONE;
9487}
9488#endif
9489
9490
Larry Hastings2f936352014-08-05 14:04:04 +10009491/*[clinic input]
9492os.fstat
9493
9494 fd : int
9495
9496Perform a stat system call on the given file descriptor.
9497
9498Like stat(), but for an open file descriptor.
9499Equivalent to os.stat(fd).
9500[clinic start generated code]*/
9501
Larry Hastings2f936352014-08-05 14:04:04 +10009502static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009503os_fstat_impl(PyObject *module, int fd)
9504/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009505{
Victor Stinner8c62be82010-05-06 00:08:46 +00009506 STRUCT_STAT st;
9507 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009508 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009509
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009510 do {
9511 Py_BEGIN_ALLOW_THREADS
9512 res = FSTAT(fd, &st);
9513 Py_END_ALLOW_THREADS
9514 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009516#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009517 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009518#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009519 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009520#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 }
Tim Peters5aa91602002-01-30 05:46:57 +00009522
Victor Stinner1c2fa782020-05-10 11:05:29 +02009523 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009524}
9525
Larry Hastings2f936352014-08-05 14:04:04 +10009526
9527/*[clinic input]
9528os.isatty -> bool
9529 fd: int
9530 /
9531
9532Return True if the fd is connected to a terminal.
9533
9534Return True if the file descriptor is an open file descriptor
9535connected to the slave end of a terminal.
9536[clinic start generated code]*/
9537
Larry Hastings2f936352014-08-05 14:04:04 +10009538static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009539os_isatty_impl(PyObject *module, int fd)
9540/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009541{
Steve Dower8fc89802015-04-12 00:26:27 -04009542 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009543 _Py_BEGIN_SUPPRESS_IPH
9544 return_value = isatty(fd);
9545 _Py_END_SUPPRESS_IPH
9546 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009547}
9548
9549
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009550#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009551/*[clinic input]
9552os.pipe
9553
9554Create a pipe.
9555
9556Returns a tuple of two file descriptors:
9557 (read_fd, write_fd)
9558[clinic start generated code]*/
9559
Larry Hastings2f936352014-08-05 14:04:04 +10009560static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009561os_pipe_impl(PyObject *module)
9562/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009563{
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009565#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009567 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009569#else
9570 int res;
9571#endif
9572
9573#ifdef MS_WINDOWS
9574 attr.nLength = sizeof(attr);
9575 attr.lpSecurityDescriptor = NULL;
9576 attr.bInheritHandle = FALSE;
9577
9578 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009579 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009580 ok = CreatePipe(&read, &write, &attr, 0);
9581 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009582 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9583 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009584 if (fds[0] == -1 || fds[1] == -1) {
9585 CloseHandle(read);
9586 CloseHandle(write);
9587 ok = 0;
9588 }
9589 }
Steve Dowerc3630612016-11-19 18:41:16 -08009590 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009591 Py_END_ALLOW_THREADS
9592
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009594 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009595#else
9596
9597#ifdef HAVE_PIPE2
9598 Py_BEGIN_ALLOW_THREADS
9599 res = pipe2(fds, O_CLOEXEC);
9600 Py_END_ALLOW_THREADS
9601
9602 if (res != 0 && errno == ENOSYS)
9603 {
9604#endif
9605 Py_BEGIN_ALLOW_THREADS
9606 res = pipe(fds);
9607 Py_END_ALLOW_THREADS
9608
9609 if (res == 0) {
9610 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9611 close(fds[0]);
9612 close(fds[1]);
9613 return NULL;
9614 }
9615 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9616 close(fds[0]);
9617 close(fds[1]);
9618 return NULL;
9619 }
9620 }
9621#ifdef HAVE_PIPE2
9622 }
9623#endif
9624
9625 if (res != 0)
9626 return PyErr_SetFromErrno(PyExc_OSError);
9627#endif /* !MS_WINDOWS */
9628 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009629}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009630#endif /* HAVE_PIPE */
9631
Larry Hastings2f936352014-08-05 14:04:04 +10009632
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009633#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009634/*[clinic input]
9635os.pipe2
9636
9637 flags: int
9638 /
9639
9640Create a pipe with flags set atomically.
9641
9642Returns a tuple of two file descriptors:
9643 (read_fd, write_fd)
9644
9645flags can be constructed by ORing together one or more of these values:
9646O_NONBLOCK, O_CLOEXEC.
9647[clinic start generated code]*/
9648
Larry Hastings2f936352014-08-05 14:04:04 +10009649static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009650os_pipe2_impl(PyObject *module, int flags)
9651/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009652{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009653 int fds[2];
9654 int res;
9655
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009656 res = pipe2(fds, flags);
9657 if (res != 0)
9658 return posix_error();
9659 return Py_BuildValue("(ii)", fds[0], fds[1]);
9660}
9661#endif /* HAVE_PIPE2 */
9662
Larry Hastings2f936352014-08-05 14:04:04 +10009663
Ross Lagerwall7807c352011-03-17 20:20:30 +02009664#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009665/*[clinic input]
9666os.writev -> Py_ssize_t
9667 fd: int
9668 buffers: object
9669 /
9670
9671Iterate over buffers, and write the contents of each to a file descriptor.
9672
9673Returns the total number of bytes written.
9674buffers must be a sequence of bytes-like objects.
9675[clinic start generated code]*/
9676
Larry Hastings2f936352014-08-05 14:04:04 +10009677static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009678os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9679/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009680{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009681 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009682 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009683 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009684 struct iovec *iov;
9685 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009686
9687 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009688 PyErr_SetString(PyExc_TypeError,
9689 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009690 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009691 }
Larry Hastings2f936352014-08-05 14:04:04 +10009692 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009693 if (cnt < 0)
9694 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009695
Larry Hastings2f936352014-08-05 14:04:04 +10009696 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9697 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009698 }
9699
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009700 do {
9701 Py_BEGIN_ALLOW_THREADS
9702 result = writev(fd, iov, cnt);
9703 Py_END_ALLOW_THREADS
9704 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009705
9706 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009707 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009708 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009709
Georg Brandl306336b2012-06-24 12:55:33 +02009710 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009711}
Larry Hastings2f936352014-08-05 14:04:04 +10009712#endif /* HAVE_WRITEV */
9713
9714
9715#ifdef HAVE_PWRITE
9716/*[clinic input]
9717os.pwrite -> Py_ssize_t
9718
9719 fd: int
9720 buffer: Py_buffer
9721 offset: Py_off_t
9722 /
9723
9724Write bytes to a file descriptor starting at a particular offset.
9725
9726Write buffer to fd, starting at offset bytes from the beginning of
9727the file. Returns the number of bytes writte. Does not change the
9728current file offset.
9729[clinic start generated code]*/
9730
Larry Hastings2f936352014-08-05 14:04:04 +10009731static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009732os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9733/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009734{
9735 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009736 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009737
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009738 do {
9739 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009740 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009741 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009742 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009743 Py_END_ALLOW_THREADS
9744 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009745
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009746 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009747 posix_error();
9748 return size;
9749}
9750#endif /* HAVE_PWRITE */
9751
Pablo Galindo4defba32018-01-27 16:16:37 +00009752#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9753/*[clinic input]
9754os.pwritev -> Py_ssize_t
9755
9756 fd: int
9757 buffers: object
9758 offset: Py_off_t
9759 flags: int = 0
9760 /
9761
9762Writes the contents of bytes-like objects to a file descriptor at a given offset.
9763
9764Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9765of bytes-like objects. Buffers are processed in array order. Entire contents of first
9766buffer is written before proceeding to second, and so on. The operating system may
9767set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9768This function writes the contents of each object to the file descriptor and returns
9769the total number of bytes written.
9770
9771The flags argument contains a bitwise OR of zero or more of the following flags:
9772
9773- RWF_DSYNC
9774- RWF_SYNC
9775
9776Using non-zero flags requires Linux 4.7 or newer.
9777[clinic start generated code]*/
9778
9779static Py_ssize_t
9780os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9781 int flags)
9782/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9783{
9784 Py_ssize_t cnt;
9785 Py_ssize_t result;
9786 int async_err = 0;
9787 struct iovec *iov;
9788 Py_buffer *buf;
9789
9790 if (!PySequence_Check(buffers)) {
9791 PyErr_SetString(PyExc_TypeError,
9792 "pwritev() arg 2 must be a sequence");
9793 return -1;
9794 }
9795
9796 cnt = PySequence_Size(buffers);
9797 if (cnt < 0) {
9798 return -1;
9799 }
9800
9801#ifndef HAVE_PWRITEV2
9802 if(flags != 0) {
9803 argument_unavailable_error("pwritev2", "flags");
9804 return -1;
9805 }
9806#endif
9807
9808 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9809 return -1;
9810 }
9811#ifdef HAVE_PWRITEV2
9812 do {
9813 Py_BEGIN_ALLOW_THREADS
9814 _Py_BEGIN_SUPPRESS_IPH
9815 result = pwritev2(fd, iov, cnt, offset, flags);
9816 _Py_END_SUPPRESS_IPH
9817 Py_END_ALLOW_THREADS
9818 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9819#else
9820 do {
9821 Py_BEGIN_ALLOW_THREADS
9822 _Py_BEGIN_SUPPRESS_IPH
9823 result = pwritev(fd, iov, cnt, offset);
9824 _Py_END_SUPPRESS_IPH
9825 Py_END_ALLOW_THREADS
9826 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9827#endif
9828
9829 iov_cleanup(iov, buf, cnt);
9830 if (result < 0) {
9831 if (!async_err) {
9832 posix_error();
9833 }
9834 return -1;
9835 }
9836
9837 return result;
9838}
9839#endif /* HAVE_PWRITEV */
9840
Pablo Galindoaac4d032019-05-31 19:39:47 +01009841#ifdef HAVE_COPY_FILE_RANGE
9842/*[clinic input]
9843
9844os.copy_file_range
9845 src: int
9846 Source file descriptor.
9847 dst: int
9848 Destination file descriptor.
9849 count: Py_ssize_t
9850 Number of bytes to copy.
9851 offset_src: object = None
9852 Starting offset in src.
9853 offset_dst: object = None
9854 Starting offset in dst.
9855
9856Copy count bytes from one file descriptor to another.
9857
9858If offset_src is None, then src is read from the current position;
9859respectively for offset_dst.
9860[clinic start generated code]*/
9861
9862static PyObject *
9863os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9864 PyObject *offset_src, PyObject *offset_dst)
9865/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9866{
9867 off_t offset_src_val, offset_dst_val;
9868 off_t *p_offset_src = NULL;
9869 off_t *p_offset_dst = NULL;
9870 Py_ssize_t ret;
9871 int async_err = 0;
9872 /* The flags argument is provided to allow
9873 * for future extensions and currently must be to 0. */
9874 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009875
9876
Pablo Galindoaac4d032019-05-31 19:39:47 +01009877 if (count < 0) {
9878 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9879 return NULL;
9880 }
9881
9882 if (offset_src != Py_None) {
9883 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9884 return NULL;
9885 }
9886 p_offset_src = &offset_src_val;
9887 }
9888
9889 if (offset_dst != Py_None) {
9890 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9891 return NULL;
9892 }
9893 p_offset_dst = &offset_dst_val;
9894 }
9895
9896 do {
9897 Py_BEGIN_ALLOW_THREADS
9898 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9899 Py_END_ALLOW_THREADS
9900 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9901
9902 if (ret < 0) {
9903 return (!async_err) ? posix_error() : NULL;
9904 }
9905
9906 return PyLong_FromSsize_t(ret);
9907}
9908#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +10009909
9910#ifdef HAVE_MKFIFO
9911/*[clinic input]
9912os.mkfifo
9913
9914 path: path_t
9915 mode: int=0o666
9916 *
9917 dir_fd: dir_fd(requires='mkfifoat')=None
9918
9919Create a "fifo" (a POSIX named pipe).
9920
9921If dir_fd is not None, it should be a file descriptor open to a directory,
9922 and path should be relative; path will then be relative to that directory.
9923dir_fd may not be implemented on your platform.
9924 If it is unavailable, using it will raise a NotImplementedError.
9925[clinic start generated code]*/
9926
Larry Hastings2f936352014-08-05 14:04:04 +10009927static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009928os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9929/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009930{
9931 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009932 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009933
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009934 do {
9935 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009936#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009937 if (dir_fd != DEFAULT_DIR_FD)
9938 result = mkfifoat(dir_fd, path->narrow, mode);
9939 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009940#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009941 result = mkfifo(path->narrow, mode);
9942 Py_END_ALLOW_THREADS
9943 } while (result != 0 && errno == EINTR &&
9944 !(async_err = PyErr_CheckSignals()));
9945 if (result != 0)
9946 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009947
9948 Py_RETURN_NONE;
9949}
9950#endif /* HAVE_MKFIFO */
9951
9952
9953#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9954/*[clinic input]
9955os.mknod
9956
9957 path: path_t
9958 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009959 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009960 *
9961 dir_fd: dir_fd(requires='mknodat')=None
9962
9963Create a node in the file system.
9964
9965Create a node in the file system (file, device special file or named pipe)
9966at path. mode specifies both the permissions to use and the
9967type of node to be created, being combined (bitwise OR) with one of
9968S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9969device defines the newly created device special file (probably using
9970os.makedev()). Otherwise device is ignored.
9971
9972If dir_fd is not None, it should be a file descriptor open to a directory,
9973 and path should be relative; path will then be relative to that directory.
9974dir_fd may not be implemented on your platform.
9975 If it is unavailable, using it will raise a NotImplementedError.
9976[clinic start generated code]*/
9977
Larry Hastings2f936352014-08-05 14:04:04 +10009978static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009979os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04009980 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009981/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009982{
9983 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009984 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009985
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009986 do {
9987 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009988#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009989 if (dir_fd != DEFAULT_DIR_FD)
9990 result = mknodat(dir_fd, path->narrow, mode, device);
9991 else
Larry Hastings2f936352014-08-05 14:04:04 +10009992#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009993 result = mknod(path->narrow, mode, device);
9994 Py_END_ALLOW_THREADS
9995 } while (result != 0 && errno == EINTR &&
9996 !(async_err = PyErr_CheckSignals()));
9997 if (result != 0)
9998 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009999
10000 Py_RETURN_NONE;
10001}
10002#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10003
10004
10005#ifdef HAVE_DEVICE_MACROS
10006/*[clinic input]
10007os.major -> unsigned_int
10008
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010009 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010010 /
10011
10012Extracts a device major number from a raw device number.
10013[clinic start generated code]*/
10014
Larry Hastings2f936352014-08-05 14:04:04 +100010015static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010016os_major_impl(PyObject *module, dev_t device)
10017/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010018{
10019 return major(device);
10020}
10021
10022
10023/*[clinic input]
10024os.minor -> unsigned_int
10025
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010026 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010027 /
10028
10029Extracts a device minor number from a raw device number.
10030[clinic start generated code]*/
10031
Larry Hastings2f936352014-08-05 14:04:04 +100010032static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010033os_minor_impl(PyObject *module, dev_t device)
10034/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010035{
10036 return minor(device);
10037}
10038
10039
10040/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010041os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010042
10043 major: int
10044 minor: int
10045 /
10046
10047Composes a raw device number from the major and minor device numbers.
10048[clinic start generated code]*/
10049
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010050static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010051os_makedev_impl(PyObject *module, int major, int minor)
10052/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010053{
10054 return makedev(major, minor);
10055}
10056#endif /* HAVE_DEVICE_MACROS */
10057
10058
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010059#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010060/*[clinic input]
10061os.ftruncate
10062
10063 fd: int
10064 length: Py_off_t
10065 /
10066
10067Truncate a file, specified by file descriptor, to a specific length.
10068[clinic start generated code]*/
10069
Larry Hastings2f936352014-08-05 14:04:04 +100010070static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010071os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10072/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010073{
10074 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010075 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010076
Steve Dowerb82e17e2019-05-23 08:45:22 -070010077 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10078 return NULL;
10079 }
10080
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010081 do {
10082 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010083 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010084#ifdef MS_WINDOWS
10085 result = _chsize_s(fd, length);
10086#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010087 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010088#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010089 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010090 Py_END_ALLOW_THREADS
10091 } while (result != 0 && errno == EINTR &&
10092 !(async_err = PyErr_CheckSignals()));
10093 if (result != 0)
10094 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010095 Py_RETURN_NONE;
10096}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010097#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010098
10099
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010100#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010101/*[clinic input]
10102os.truncate
10103 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10104 length: Py_off_t
10105
10106Truncate a file, specified by path, to a specific length.
10107
10108On some platforms, path may also be specified as an open file descriptor.
10109 If this functionality is unavailable, using it raises an exception.
10110[clinic start generated code]*/
10111
Larry Hastings2f936352014-08-05 14:04:04 +100010112static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010113os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10114/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010115{
10116 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010117#ifdef MS_WINDOWS
10118 int fd;
10119#endif
10120
10121 if (path->fd != -1)
10122 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010123
Steve Dowerb82e17e2019-05-23 08:45:22 -070010124 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10125 return NULL;
10126 }
10127
Larry Hastings2f936352014-08-05 14:04:04 +100010128 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010129 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010130#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010131 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010132 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010133 result = -1;
10134 else {
10135 result = _chsize_s(fd, length);
10136 close(fd);
10137 if (result < 0)
10138 errno = result;
10139 }
10140#else
10141 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010142#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010143 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010144 Py_END_ALLOW_THREADS
10145 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010146 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010147
10148 Py_RETURN_NONE;
10149}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010150#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010151
Ross Lagerwall7807c352011-03-17 20:20:30 +020010152
Victor Stinnerd6b17692014-09-30 12:20:05 +020010153/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10154 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10155 defined, which is the case in Python on AIX. AIX bug report:
10156 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10157#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10158# define POSIX_FADVISE_AIX_BUG
10159#endif
10160
Victor Stinnerec39e262014-09-30 12:35:58 +020010161
Victor Stinnerd6b17692014-09-30 12:20:05 +020010162#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010163/*[clinic input]
10164os.posix_fallocate
10165
10166 fd: int
10167 offset: Py_off_t
10168 length: Py_off_t
10169 /
10170
10171Ensure a file has allocated at least a particular number of bytes on disk.
10172
10173Ensure that the file specified by fd encompasses a range of bytes
10174starting at offset bytes from the beginning and continuing for length bytes.
10175[clinic start generated code]*/
10176
Larry Hastings2f936352014-08-05 14:04:04 +100010177static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010178os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010179 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010180/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010181{
10182 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010183 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010184
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010185 do {
10186 Py_BEGIN_ALLOW_THREADS
10187 result = posix_fallocate(fd, offset, length);
10188 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010189 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10190
10191 if (result == 0)
10192 Py_RETURN_NONE;
10193
10194 if (async_err)
10195 return NULL;
10196
10197 errno = result;
10198 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010199}
Victor Stinnerec39e262014-09-30 12:35:58 +020010200#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010201
Ross Lagerwall7807c352011-03-17 20:20:30 +020010202
Victor Stinnerd6b17692014-09-30 12:20:05 +020010203#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010204/*[clinic input]
10205os.posix_fadvise
10206
10207 fd: int
10208 offset: Py_off_t
10209 length: Py_off_t
10210 advice: int
10211 /
10212
10213Announce an intention to access data in a specific pattern.
10214
10215Announce an intention to access data in a specific pattern, thus allowing
10216the kernel to make optimizations.
10217The advice applies to the region of the file specified by fd starting at
10218offset and continuing for length bytes.
10219advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10220POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10221POSIX_FADV_DONTNEED.
10222[clinic start generated code]*/
10223
Larry Hastings2f936352014-08-05 14:04:04 +100010224static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010225os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010226 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010227/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010228{
10229 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010230 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010231
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010232 do {
10233 Py_BEGIN_ALLOW_THREADS
10234 result = posix_fadvise(fd, offset, length, advice);
10235 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010236 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10237
10238 if (result == 0)
10239 Py_RETURN_NONE;
10240
10241 if (async_err)
10242 return NULL;
10243
10244 errno = result;
10245 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010246}
Victor Stinnerec39e262014-09-30 12:35:58 +020010247#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010249
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010250#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010251static PyObject*
10252win32_putenv(PyObject *name, PyObject *value)
10253{
10254 /* Search from index 1 because on Windows starting '=' is allowed for
10255 defining hidden environment variables. */
10256 if (PyUnicode_GET_LENGTH(name) == 0 ||
10257 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10258 {
10259 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10260 return NULL;
10261 }
10262 PyObject *unicode;
10263 if (value != NULL) {
10264 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10265 }
10266 else {
10267 unicode = PyUnicode_FromFormat("%U=", name);
10268 }
10269 if (unicode == NULL) {
10270 return NULL;
10271 }
10272
10273 Py_ssize_t size;
10274 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10275 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10276 Py_DECREF(unicode);
10277
10278 if (env == NULL) {
10279 return NULL;
10280 }
10281 if (size > _MAX_ENV) {
10282 PyErr_Format(PyExc_ValueError,
10283 "the environment variable is longer than %u characters",
10284 _MAX_ENV);
10285 PyMem_Free(env);
10286 return NULL;
10287 }
10288
10289 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10290 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10291 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10292
10293 Prefer _wputenv() to be compatible with C libraries using CRT
10294 variables and CRT functions using these variables (ex: getenv()). */
10295 int err = _wputenv(env);
10296 PyMem_Free(env);
10297
10298 if (err) {
10299 posix_error();
10300 return NULL;
10301 }
10302
10303 Py_RETURN_NONE;
10304}
10305#endif
10306
10307
10308#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010309/*[clinic input]
10310os.putenv
10311
10312 name: unicode
10313 value: unicode
10314 /
10315
10316Change or add an environment variable.
10317[clinic start generated code]*/
10318
Larry Hastings2f936352014-08-05 14:04:04 +100010319static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010320os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10321/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010322{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010323 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10324 return NULL;
10325 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010326 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010327}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010328#else
Larry Hastings2f936352014-08-05 14:04:04 +100010329/*[clinic input]
10330os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010331
Larry Hastings2f936352014-08-05 14:04:04 +100010332 name: FSConverter
10333 value: FSConverter
10334 /
10335
10336Change or add an environment variable.
10337[clinic start generated code]*/
10338
Larry Hastings2f936352014-08-05 14:04:04 +100010339static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010340os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10341/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010342{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010343 const char *name_string = PyBytes_AS_STRING(name);
10344 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010345
Serhiy Storchaka77703942017-06-25 07:33:01 +030010346 if (strchr(name_string, '=') != NULL) {
10347 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10348 return NULL;
10349 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010350
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010351 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10352 return NULL;
10353 }
10354
Victor Stinnerb477d192020-01-22 22:48:16 +010010355 if (setenv(name_string, value_string, 1)) {
10356 return posix_error();
10357 }
Larry Hastings2f936352014-08-05 14:04:04 +100010358 Py_RETURN_NONE;
10359}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010360#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010361
10362
Victor Stinner161e7b32020-01-24 11:53:44 +010010363#ifdef MS_WINDOWS
10364/*[clinic input]
10365os.unsetenv
10366 name: unicode
10367 /
10368
10369Delete an environment variable.
10370[clinic start generated code]*/
10371
10372static PyObject *
10373os_unsetenv_impl(PyObject *module, PyObject *name)
10374/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10375{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010376 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10377 return NULL;
10378 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010379 return win32_putenv(name, NULL);
10380}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010381#else
Larry Hastings2f936352014-08-05 14:04:04 +100010382/*[clinic input]
10383os.unsetenv
10384 name: FSConverter
10385 /
10386
10387Delete an environment variable.
10388[clinic start generated code]*/
10389
Larry Hastings2f936352014-08-05 14:04:04 +100010390static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010391os_unsetenv_impl(PyObject *module, PyObject *name)
10392/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010393{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010394 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10395 return NULL;
10396 }
Victor Stinner984890f2011-11-24 13:53:38 +010010397#ifdef HAVE_BROKEN_UNSETENV
10398 unsetenv(PyBytes_AS_STRING(name));
10399#else
Victor Stinner161e7b32020-01-24 11:53:44 +010010400 int err = unsetenv(PyBytes_AS_STRING(name));
10401 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010010402 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010010403 }
Victor Stinner984890f2011-11-24 13:53:38 +010010404#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010405
Victor Stinner84ae1182010-05-06 22:05:07 +000010406 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010407}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010408#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000010409
Larry Hastings2f936352014-08-05 14:04:04 +100010410
10411/*[clinic input]
10412os.strerror
10413
10414 code: int
10415 /
10416
10417Translate an error code to a message string.
10418[clinic start generated code]*/
10419
Larry Hastings2f936352014-08-05 14:04:04 +100010420static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010421os_strerror_impl(PyObject *module, int code)
10422/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010423{
10424 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010425 if (message == NULL) {
10426 PyErr_SetString(PyExc_ValueError,
10427 "strerror() argument out of range");
10428 return NULL;
10429 }
Victor Stinner1b579672011-12-17 05:47:23 +010010430 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010431}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010432
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010433
Guido van Rossumc9641791998-08-04 15:26:23 +000010434#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010435#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010436/*[clinic input]
10437os.WCOREDUMP -> bool
10438
10439 status: int
10440 /
10441
10442Return True if the process returning status was dumped to a core file.
10443[clinic start generated code]*/
10444
Larry Hastings2f936352014-08-05 14:04:04 +100010445static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010446os_WCOREDUMP_impl(PyObject *module, int status)
10447/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010448{
10449 WAIT_TYPE wait_status;
10450 WAIT_STATUS_INT(wait_status) = status;
10451 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010452}
10453#endif /* WCOREDUMP */
10454
Larry Hastings2f936352014-08-05 14:04:04 +100010455
Fred Drake106c1a02002-04-23 15:58:02 +000010456#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010457/*[clinic input]
10458os.WIFCONTINUED -> bool
10459
10460 status: int
10461
10462Return True if a particular process was continued from a job control stop.
10463
10464Return True if the process returning status was continued from a
10465job control stop.
10466[clinic start generated code]*/
10467
Larry Hastings2f936352014-08-05 14:04:04 +100010468static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010469os_WIFCONTINUED_impl(PyObject *module, int status)
10470/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010471{
10472 WAIT_TYPE wait_status;
10473 WAIT_STATUS_INT(wait_status) = status;
10474 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010475}
10476#endif /* WIFCONTINUED */
10477
Larry Hastings2f936352014-08-05 14:04:04 +100010478
Guido van Rossumc9641791998-08-04 15:26:23 +000010479#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010480/*[clinic input]
10481os.WIFSTOPPED -> bool
10482
10483 status: int
10484
10485Return True if the process returning status was stopped.
10486[clinic start generated code]*/
10487
Larry Hastings2f936352014-08-05 14:04:04 +100010488static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010489os_WIFSTOPPED_impl(PyObject *module, int status)
10490/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010491{
10492 WAIT_TYPE wait_status;
10493 WAIT_STATUS_INT(wait_status) = status;
10494 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010495}
10496#endif /* WIFSTOPPED */
10497
Larry Hastings2f936352014-08-05 14:04:04 +100010498
Guido van Rossumc9641791998-08-04 15:26:23 +000010499#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010500/*[clinic input]
10501os.WIFSIGNALED -> bool
10502
10503 status: int
10504
10505Return True if the process returning status was terminated by a signal.
10506[clinic start generated code]*/
10507
Larry Hastings2f936352014-08-05 14:04:04 +100010508static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010509os_WIFSIGNALED_impl(PyObject *module, int status)
10510/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010511{
10512 WAIT_TYPE wait_status;
10513 WAIT_STATUS_INT(wait_status) = status;
10514 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010515}
10516#endif /* WIFSIGNALED */
10517
Larry Hastings2f936352014-08-05 14:04:04 +100010518
Guido van Rossumc9641791998-08-04 15:26:23 +000010519#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010520/*[clinic input]
10521os.WIFEXITED -> bool
10522
10523 status: int
10524
10525Return True if the process returning status exited via the exit() system call.
10526[clinic start generated code]*/
10527
Larry Hastings2f936352014-08-05 14:04:04 +100010528static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010529os_WIFEXITED_impl(PyObject *module, int status)
10530/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010531{
10532 WAIT_TYPE wait_status;
10533 WAIT_STATUS_INT(wait_status) = status;
10534 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010535}
10536#endif /* WIFEXITED */
10537
Larry Hastings2f936352014-08-05 14:04:04 +100010538
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010539#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010540/*[clinic input]
10541os.WEXITSTATUS -> int
10542
10543 status: int
10544
10545Return the process return code from status.
10546[clinic start generated code]*/
10547
Larry Hastings2f936352014-08-05 14:04:04 +100010548static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010549os_WEXITSTATUS_impl(PyObject *module, int status)
10550/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010551{
10552 WAIT_TYPE wait_status;
10553 WAIT_STATUS_INT(wait_status) = status;
10554 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010555}
10556#endif /* WEXITSTATUS */
10557
Larry Hastings2f936352014-08-05 14:04:04 +100010558
Guido van Rossumc9641791998-08-04 15:26:23 +000010559#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010560/*[clinic input]
10561os.WTERMSIG -> int
10562
10563 status: int
10564
10565Return the signal that terminated the process that provided the status value.
10566[clinic start generated code]*/
10567
Larry Hastings2f936352014-08-05 14:04:04 +100010568static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010569os_WTERMSIG_impl(PyObject *module, int status)
10570/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010571{
10572 WAIT_TYPE wait_status;
10573 WAIT_STATUS_INT(wait_status) = status;
10574 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010575}
10576#endif /* WTERMSIG */
10577
Larry Hastings2f936352014-08-05 14:04:04 +100010578
Guido van Rossumc9641791998-08-04 15:26:23 +000010579#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010580/*[clinic input]
10581os.WSTOPSIG -> int
10582
10583 status: int
10584
10585Return the signal that stopped the process that provided the status value.
10586[clinic start generated code]*/
10587
Larry Hastings2f936352014-08-05 14:04:04 +100010588static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010589os_WSTOPSIG_impl(PyObject *module, int status)
10590/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010591{
10592 WAIT_TYPE wait_status;
10593 WAIT_STATUS_INT(wait_status) = status;
10594 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010595}
10596#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010597#endif /* HAVE_SYS_WAIT_H */
10598
10599
Thomas Wouters477c8d52006-05-27 19:21:47 +000010600#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010601#ifdef _SCO_DS
10602/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10603 needed definitions in sys/statvfs.h */
10604#define _SVID3
10605#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010606#include <sys/statvfs.h>
10607
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010608static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020010609_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
10610 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080010611 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010612 if (v == NULL)
10613 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010614
10615#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010616 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10617 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10618 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10619 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10620 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10621 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10622 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10623 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10624 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10625 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010626#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010627 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10628 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10629 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010630 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010632 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010633 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010634 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010635 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010636 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010638 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010639 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010640 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010641 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10642 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010643#endif
Michael Felt502d5512018-01-05 13:01:58 +010010644/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10645 * (issue #32390). */
10646#if defined(_AIX) && defined(_ALL_SOURCE)
10647 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10648#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010649 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010650#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010651 if (PyErr_Occurred()) {
10652 Py_DECREF(v);
10653 return NULL;
10654 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010655
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010657}
10658
Larry Hastings2f936352014-08-05 14:04:04 +100010659
10660/*[clinic input]
10661os.fstatvfs
10662 fd: int
10663 /
10664
10665Perform an fstatvfs system call on the given fd.
10666
10667Equivalent to statvfs(fd).
10668[clinic start generated code]*/
10669
Larry Hastings2f936352014-08-05 14:04:04 +100010670static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010671os_fstatvfs_impl(PyObject *module, int fd)
10672/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010673{
10674 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010675 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010677
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010678 do {
10679 Py_BEGIN_ALLOW_THREADS
10680 result = fstatvfs(fd, &st);
10681 Py_END_ALLOW_THREADS
10682 } while (result != 0 && errno == EINTR &&
10683 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010684 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010685 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010686
Victor Stinner1c2fa782020-05-10 11:05:29 +020010687 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010688}
Larry Hastings2f936352014-08-05 14:04:04 +100010689#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010690
10691
Thomas Wouters477c8d52006-05-27 19:21:47 +000010692#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010693#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010694/*[clinic input]
10695os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010696
Larry Hastings2f936352014-08-05 14:04:04 +100010697 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10698
10699Perform a statvfs system call on the given path.
10700
10701path may always be specified as a string.
10702On some platforms, path may also be specified as an open file descriptor.
10703 If this functionality is unavailable, using it raises an exception.
10704[clinic start generated code]*/
10705
Larry Hastings2f936352014-08-05 14:04:04 +100010706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010707os_statvfs_impl(PyObject *module, path_t *path)
10708/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010709{
10710 int result;
10711 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010712
10713 Py_BEGIN_ALLOW_THREADS
10714#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010715 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010716#ifdef __APPLE__
10717 /* handle weak-linking on Mac OS X 10.3 */
10718 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010719 fd_specified("statvfs", path->fd);
10720 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010721 }
10722#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010723 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010724 }
10725 else
10726#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010727 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010728 Py_END_ALLOW_THREADS
10729
10730 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010731 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010732 }
10733
Victor Stinner1c2fa782020-05-10 11:05:29 +020010734 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010735}
Larry Hastings2f936352014-08-05 14:04:04 +100010736#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10737
Guido van Rossum94f6f721999-01-06 18:42:14 +000010738
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010739#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010740/*[clinic input]
10741os._getdiskusage
10742
Steve Dower23ad6d02018-02-22 10:39:10 -080010743 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010744
10745Return disk usage statistics about the given path as a (total, free) tuple.
10746[clinic start generated code]*/
10747
Larry Hastings2f936352014-08-05 14:04:04 +100010748static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010749os__getdiskusage_impl(PyObject *module, path_t *path)
10750/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010751{
10752 BOOL retval;
10753 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010754 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010755
10756 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010757 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010758 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010759 if (retval == 0) {
10760 if (GetLastError() == ERROR_DIRECTORY) {
10761 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010762
Joe Pamerc8c02492018-09-25 10:57:36 -040010763 dir_path = PyMem_New(wchar_t, path->length + 1);
10764 if (dir_path == NULL) {
10765 return PyErr_NoMemory();
10766 }
10767
10768 wcscpy_s(dir_path, path->length + 1, path->wide);
10769
10770 if (_dirnameW(dir_path) != -1) {
10771 Py_BEGIN_ALLOW_THREADS
10772 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10773 Py_END_ALLOW_THREADS
10774 }
10775 /* Record the last error in case it's modified by PyMem_Free. */
10776 err = GetLastError();
10777 PyMem_Free(dir_path);
10778 if (retval) {
10779 goto success;
10780 }
10781 }
10782 return PyErr_SetFromWindowsErr(err);
10783 }
10784
10785success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010786 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10787}
Larry Hastings2f936352014-08-05 14:04:04 +100010788#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010789
10790
Fred Drakec9680921999-12-13 16:37:25 +000010791/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10792 * It maps strings representing configuration variable names to
10793 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010794 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010795 * rarely-used constants. There are three separate tables that use
10796 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010797 *
10798 * This code is always included, even if none of the interfaces that
10799 * need it are included. The #if hackery needed to avoid it would be
10800 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010801 */
10802struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010803 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010804 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010805};
10806
Fred Drake12c6e2d1999-12-14 21:25:03 +000010807static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010808conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010809 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010810{
Christian Heimes217cfd12007-12-02 14:31:20 +000010811 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010812 int value = _PyLong_AsInt(arg);
10813 if (value == -1 && PyErr_Occurred())
10814 return 0;
10815 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010816 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010817 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010818 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010819 /* look up the value in the table using a binary search */
10820 size_t lo = 0;
10821 size_t mid;
10822 size_t hi = tablesize;
10823 int cmp;
10824 const char *confname;
10825 if (!PyUnicode_Check(arg)) {
10826 PyErr_SetString(PyExc_TypeError,
10827 "configuration names must be strings or integers");
10828 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010829 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010830 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010831 if (confname == NULL)
10832 return 0;
10833 while (lo < hi) {
10834 mid = (lo + hi) / 2;
10835 cmp = strcmp(confname, table[mid].name);
10836 if (cmp < 0)
10837 hi = mid;
10838 else if (cmp > 0)
10839 lo = mid + 1;
10840 else {
10841 *valuep = table[mid].value;
10842 return 1;
10843 }
10844 }
10845 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10846 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010848}
10849
10850
10851#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10852static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010853#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010855#endif
10856#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010857 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010858#endif
Fred Drakec9680921999-12-13 16:37:25 +000010859#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010860 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010861#endif
10862#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010863 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010864#endif
10865#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010866 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010867#endif
10868#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010869 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010870#endif
10871#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010873#endif
10874#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010875 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010876#endif
10877#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010878 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010879#endif
10880#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010882#endif
10883#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010884 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010885#endif
10886#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010887 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010888#endif
10889#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010890 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010891#endif
10892#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010894#endif
10895#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010896 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010897#endif
10898#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010899 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010900#endif
10901#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010903#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010904#ifdef _PC_ACL_ENABLED
10905 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10906#endif
10907#ifdef _PC_MIN_HOLE_SIZE
10908 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10909#endif
10910#ifdef _PC_ALLOC_SIZE_MIN
10911 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10912#endif
10913#ifdef _PC_REC_INCR_XFER_SIZE
10914 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10915#endif
10916#ifdef _PC_REC_MAX_XFER_SIZE
10917 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10918#endif
10919#ifdef _PC_REC_MIN_XFER_SIZE
10920 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10921#endif
10922#ifdef _PC_REC_XFER_ALIGN
10923 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10924#endif
10925#ifdef _PC_SYMLINK_MAX
10926 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10927#endif
10928#ifdef _PC_XATTR_ENABLED
10929 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10930#endif
10931#ifdef _PC_XATTR_EXISTS
10932 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10933#endif
10934#ifdef _PC_TIMESTAMP_RESOLUTION
10935 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10936#endif
Fred Drakec9680921999-12-13 16:37:25 +000010937};
10938
Fred Drakec9680921999-12-13 16:37:25 +000010939static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010940conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010941{
10942 return conv_confname(arg, valuep, posix_constants_pathconf,
10943 sizeof(posix_constants_pathconf)
10944 / sizeof(struct constdef));
10945}
10946#endif
10947
Larry Hastings2f936352014-08-05 14:04:04 +100010948
Fred Drakec9680921999-12-13 16:37:25 +000010949#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010950/*[clinic input]
10951os.fpathconf -> long
10952
10953 fd: int
10954 name: path_confname
10955 /
10956
10957Return the configuration limit name for the file descriptor fd.
10958
10959If there is no limit, return -1.
10960[clinic start generated code]*/
10961
Larry Hastings2f936352014-08-05 14:04:04 +100010962static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010963os_fpathconf_impl(PyObject *module, int fd, int name)
10964/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010965{
10966 long limit;
10967
10968 errno = 0;
10969 limit = fpathconf(fd, name);
10970 if (limit == -1 && errno != 0)
10971 posix_error();
10972
10973 return limit;
10974}
10975#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010976
10977
10978#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010979/*[clinic input]
10980os.pathconf -> long
10981 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
10982 name: path_confname
10983
10984Return the configuration limit name for the file or directory path.
10985
10986If there is no limit, return -1.
10987On some platforms, path may also be specified as an open file descriptor.
10988 If this functionality is unavailable, using it raises an exception.
10989[clinic start generated code]*/
10990
Larry Hastings2f936352014-08-05 14:04:04 +100010991static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010992os_pathconf_impl(PyObject *module, path_t *path, int name)
10993/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010994{
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000010996
Victor Stinner8c62be82010-05-06 00:08:46 +000010997 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020010998#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010999 if (path->fd != -1)
11000 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011001 else
11002#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011003 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 if (limit == -1 && errno != 0) {
11005 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011006 /* could be a path or name problem */
11007 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011008 else
Larry Hastings2f936352014-08-05 14:04:04 +100011009 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 }
Larry Hastings2f936352014-08-05 14:04:04 +100011011
11012 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011013}
Larry Hastings2f936352014-08-05 14:04:04 +100011014#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011015
11016#ifdef HAVE_CONFSTR
11017static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011018#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011020#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011021#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011023#endif
11024#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011025 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011026#endif
Fred Draked86ed291999-12-15 15:34:33 +000011027#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011028 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011029#endif
11030#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011031 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011032#endif
11033#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011034 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011035#endif
11036#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011037 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011038#endif
Fred Drakec9680921999-12-13 16:37:25 +000011039#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011040 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011041#endif
11042#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011043 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011044#endif
11045#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011046 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011047#endif
11048#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011049 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011050#endif
11051#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011053#endif
11054#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011055 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011056#endif
11057#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011058 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011059#endif
11060#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011061 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011062#endif
Fred Draked86ed291999-12-15 15:34:33 +000011063#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011065#endif
Fred Drakec9680921999-12-13 16:37:25 +000011066#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011068#endif
Fred Draked86ed291999-12-15 15:34:33 +000011069#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011070 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011071#endif
11072#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011074#endif
11075#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011076 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011077#endif
11078#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011079 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011080#endif
Fred Drakec9680921999-12-13 16:37:25 +000011081#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011082 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011083#endif
11084#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011086#endif
11087#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011088 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011089#endif
11090#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011091 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011092#endif
11093#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011095#endif
11096#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011097 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011098#endif
11099#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011100 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011101#endif
11102#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011103 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011104#endif
11105#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011107#endif
11108#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011110#endif
11111#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011112 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011113#endif
11114#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011116#endif
11117#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011118 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011119#endif
11120#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011121 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011122#endif
11123#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011124 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011125#endif
11126#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011128#endif
Fred Draked86ed291999-12-15 15:34:33 +000011129#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011131#endif
11132#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011133 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011134#endif
11135#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011136 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011137#endif
11138#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011139 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011140#endif
11141#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011142 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011143#endif
11144#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011145 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011146#endif
11147#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011149#endif
11150#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011152#endif
11153#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011155#endif
11156#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011158#endif
11159#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011161#endif
11162#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011164#endif
11165#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011167#endif
Fred Drakec9680921999-12-13 16:37:25 +000011168};
11169
11170static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011171conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011172{
11173 return conv_confname(arg, valuep, posix_constants_confstr,
11174 sizeof(posix_constants_confstr)
11175 / sizeof(struct constdef));
11176}
11177
Larry Hastings2f936352014-08-05 14:04:04 +100011178
11179/*[clinic input]
11180os.confstr
11181
11182 name: confstr_confname
11183 /
11184
11185Return a string-valued system configuration variable.
11186[clinic start generated code]*/
11187
Larry Hastings2f936352014-08-05 14:04:04 +100011188static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011189os_confstr_impl(PyObject *module, int name)
11190/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011191{
11192 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011193 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011194 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011195
Victor Stinnercb043522010-09-10 23:49:04 +000011196 errno = 0;
11197 len = confstr(name, buffer, sizeof(buffer));
11198 if (len == 0) {
11199 if (errno) {
11200 posix_error();
11201 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011202 }
11203 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011204 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011205 }
11206 }
Victor Stinnercb043522010-09-10 23:49:04 +000011207
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011208 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011209 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011210 char *buf = PyMem_Malloc(len);
11211 if (buf == NULL)
11212 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011213 len2 = confstr(name, buf, len);
11214 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011215 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011216 PyMem_Free(buf);
11217 }
11218 else
11219 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011220 return result;
11221}
Larry Hastings2f936352014-08-05 14:04:04 +100011222#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011223
11224
11225#ifdef HAVE_SYSCONF
11226static struct constdef posix_constants_sysconf[] = {
11227#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011228 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011229#endif
11230#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011231 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011232#endif
11233#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011234 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011235#endif
11236#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011237 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011238#endif
11239#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011240 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011241#endif
11242#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011243 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011244#endif
11245#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011246 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011247#endif
11248#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011249 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011250#endif
11251#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011252 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011253#endif
11254#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011255 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011256#endif
Fred Draked86ed291999-12-15 15:34:33 +000011257#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011258 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011259#endif
11260#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011261 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011262#endif
Fred Drakec9680921999-12-13 16:37:25 +000011263#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011264 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011265#endif
Fred Drakec9680921999-12-13 16:37:25 +000011266#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011267 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011268#endif
11269#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011270 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011271#endif
11272#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011273 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011274#endif
11275#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011276 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011277#endif
11278#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011279 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011280#endif
Fred Draked86ed291999-12-15 15:34:33 +000011281#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011282 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011283#endif
Fred Drakec9680921999-12-13 16:37:25 +000011284#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011285 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011286#endif
11287#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011288 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011289#endif
11290#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011291 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011292#endif
11293#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011295#endif
11296#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011297 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011298#endif
Fred Draked86ed291999-12-15 15:34:33 +000011299#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011300 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011301#endif
Fred Drakec9680921999-12-13 16:37:25 +000011302#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011303 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011304#endif
11305#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011306 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011307#endif
11308#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011309 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011310#endif
11311#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011313#endif
11314#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011315 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011316#endif
11317#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011318 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011319#endif
11320#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011321 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011322#endif
11323#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011324 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011325#endif
11326#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011327 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011328#endif
11329#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011331#endif
11332#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011334#endif
11335#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011337#endif
11338#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011339 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011340#endif
11341#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011342 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011343#endif
11344#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011345 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011346#endif
11347#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011348 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011349#endif
11350#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011351 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011352#endif
11353#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011355#endif
11356#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011357 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011358#endif
11359#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011361#endif
11362#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011363 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011364#endif
11365#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011366 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011367#endif
11368#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011369 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011370#endif
Fred Draked86ed291999-12-15 15:34:33 +000011371#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011373#endif
Fred Drakec9680921999-12-13 16:37:25 +000011374#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011376#endif
11377#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011379#endif
11380#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011382#endif
Fred Draked86ed291999-12-15 15:34:33 +000011383#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011385#endif
Fred Drakec9680921999-12-13 16:37:25 +000011386#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011388#endif
Fred Draked86ed291999-12-15 15:34:33 +000011389#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011391#endif
11392#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011394#endif
Fred Drakec9680921999-12-13 16:37:25 +000011395#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011397#endif
11398#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011399 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011400#endif
11401#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011403#endif
11404#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011406#endif
Fred Draked86ed291999-12-15 15:34:33 +000011407#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011408 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011409#endif
Fred Drakec9680921999-12-13 16:37:25 +000011410#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011412#endif
11413#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011415#endif
11416#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011418#endif
11419#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011420 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011421#endif
11422#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011424#endif
11425#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011427#endif
11428#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011430#endif
Fred Draked86ed291999-12-15 15:34:33 +000011431#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011432 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011433#endif
Fred Drakec9680921999-12-13 16:37:25 +000011434#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011435 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011436#endif
11437#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011438 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011439#endif
Fred Draked86ed291999-12-15 15:34:33 +000011440#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011442#endif
Fred Drakec9680921999-12-13 16:37:25 +000011443#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011445#endif
11446#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011447 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011448#endif
11449#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011450 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011451#endif
11452#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011453 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011454#endif
11455#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011456 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011457#endif
11458#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011459 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011460#endif
11461#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011462 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011463#endif
11464#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011466#endif
11467#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011469#endif
Fred Draked86ed291999-12-15 15:34:33 +000011470#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011472#endif
11473#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011475#endif
Fred Drakec9680921999-12-13 16:37:25 +000011476#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011477 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011478#endif
11479#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011480 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011481#endif
11482#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011484#endif
11485#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011486 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011487#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030011488#ifdef _SC_AIX_REALMEM
11489 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
11490#endif
Fred Drakec9680921999-12-13 16:37:25 +000011491#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011492 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011493#endif
11494#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011495 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011496#endif
11497#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011498 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011499#endif
11500#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011501 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011502#endif
11503#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011504 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011505#endif
11506#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011507 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011508#endif
11509#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011510 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011511#endif
11512#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011513 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011514#endif
11515#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011516 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011517#endif
11518#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011519 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011520#endif
11521#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011522 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011523#endif
11524#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011525 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011526#endif
11527#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011529#endif
11530#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011531 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011532#endif
11533#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011535#endif
11536#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011537 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011538#endif
11539#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011540 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011541#endif
11542#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011544#endif
11545#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011547#endif
11548#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011550#endif
11551#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011553#endif
11554#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011556#endif
11557#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011559#endif
11560#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011562#endif
11563#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011564 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011565#endif
11566#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011567 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011568#endif
11569#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011570 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011571#endif
11572#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011574#endif
11575#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011576 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011577#endif
11578#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011579 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011580#endif
11581#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011583#endif
Fred Draked86ed291999-12-15 15:34:33 +000011584#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011585 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011586#endif
Fred Drakec9680921999-12-13 16:37:25 +000011587#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011588 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011589#endif
11590#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011591 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011592#endif
11593#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011595#endif
11596#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011597 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011598#endif
11599#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011600 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011601#endif
11602#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011603 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011604#endif
11605#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011606 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011607#endif
11608#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011609 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011610#endif
11611#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011612 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011613#endif
11614#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011615 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011616#endif
11617#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011618 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011619#endif
11620#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011621 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011622#endif
11623#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011624 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011625#endif
11626#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011627 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011628#endif
11629#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011630 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011631#endif
11632#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011633 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011634#endif
11635#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011636 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011637#endif
11638#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011639 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011640#endif
11641#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011642 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011643#endif
11644#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011645 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011646#endif
11647#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011648 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011649#endif
11650#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011651 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011652#endif
11653#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011654 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011655#endif
11656#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011657 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011658#endif
11659#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011660 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011661#endif
11662#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011663 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011664#endif
11665#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011666 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011667#endif
11668#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011669 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011670#endif
11671#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011672 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011673#endif
11674#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011675 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011676#endif
11677#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011678 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011679#endif
11680#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011681 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011682#endif
11683#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011684 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011685#endif
11686#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011687 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011688#endif
11689#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011690 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011691#endif
11692#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011693 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011694#endif
11695#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011696 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011697#endif
11698#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011699 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011700#endif
11701#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011702 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011703#endif
11704#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011705 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011706#endif
11707#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011708 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011709#endif
11710#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011711 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011712#endif
11713#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011714 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011715#endif
11716#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011717 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011718#endif
11719#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011720 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011721#endif
11722};
11723
11724static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011725conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011726{
11727 return conv_confname(arg, valuep, posix_constants_sysconf,
11728 sizeof(posix_constants_sysconf)
11729 / sizeof(struct constdef));
11730}
11731
Larry Hastings2f936352014-08-05 14:04:04 +100011732
11733/*[clinic input]
11734os.sysconf -> long
11735 name: sysconf_confname
11736 /
11737
11738Return an integer-valued system configuration variable.
11739[clinic start generated code]*/
11740
Larry Hastings2f936352014-08-05 14:04:04 +100011741static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011742os_sysconf_impl(PyObject *module, int name)
11743/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011744{
11745 long value;
11746
11747 errno = 0;
11748 value = sysconf(name);
11749 if (value == -1 && errno != 0)
11750 posix_error();
11751 return value;
11752}
11753#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011754
11755
Fred Drakebec628d1999-12-15 18:31:10 +000011756/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011757 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011758 * the exported dictionaries that are used to publish information about the
11759 * names available on the host platform.
11760 *
11761 * Sorting the table at runtime ensures that the table is properly ordered
11762 * when used, even for platforms we're not able to test on. It also makes
11763 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011764 */
Fred Drakebec628d1999-12-15 18:31:10 +000011765
11766static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011767cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011768{
11769 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011770 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011771 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011772 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011773
11774 return strcmp(c1->name, c2->name);
11775}
11776
11777static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011778setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011779 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011780{
Fred Drakebec628d1999-12-15 18:31:10 +000011781 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011782 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011783
11784 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11785 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011786 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011787 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011788
Barry Warsaw3155db32000-04-13 15:20:40 +000011789 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011790 PyObject *o = PyLong_FromLong(table[i].value);
11791 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11792 Py_XDECREF(o);
11793 Py_DECREF(d);
11794 return -1;
11795 }
11796 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011797 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011798 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011799}
11800
Fred Drakebec628d1999-12-15 18:31:10 +000011801/* Return -1 on failure, 0 on success. */
11802static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011803setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011804{
11805#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011806 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011807 sizeof(posix_constants_pathconf)
11808 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011809 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011810 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011811#endif
11812#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011813 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011814 sizeof(posix_constants_confstr)
11815 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011816 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011817 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011818#endif
11819#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011820 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011821 sizeof(posix_constants_sysconf)
11822 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011823 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011824 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011825#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011826 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011827}
Fred Draked86ed291999-12-15 15:34:33 +000011828
11829
Larry Hastings2f936352014-08-05 14:04:04 +100011830/*[clinic input]
11831os.abort
11832
11833Abort the interpreter immediately.
11834
11835This function 'dumps core' or otherwise fails in the hardest way possible
11836on the hosting operating system. This function never returns.
11837[clinic start generated code]*/
11838
Larry Hastings2f936352014-08-05 14:04:04 +100011839static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011840os_abort_impl(PyObject *module)
11841/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011842{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011843 abort();
11844 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011845#ifndef __clang__
11846 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11847 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11848 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011849 Py_FatalError("abort() called from Python code didn't abort!");
11850 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011851#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011852}
Fred Drakebec628d1999-12-15 18:31:10 +000011853
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011854#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011855/* Grab ShellExecute dynamically from shell32 */
11856static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011857static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11858 LPCWSTR, INT);
11859static int
11860check_ShellExecute()
11861{
11862 HINSTANCE hShell32;
11863
11864 /* only recheck */
11865 if (-1 == has_ShellExecute) {
11866 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011867 /* Security note: this call is not vulnerable to "DLL hijacking".
11868 SHELL32 is part of "KnownDLLs" and so Windows always load
11869 the system SHELL32.DLL, even if there is another SHELL32.DLL
11870 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011871 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011872 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011873 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11874 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011875 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011876 } else {
11877 has_ShellExecute = 0;
11878 }
Tony Roberts4860f012019-02-02 18:16:42 +010011879 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011880 }
11881 return has_ShellExecute;
11882}
11883
11884
Steve Dowercc16be82016-09-08 10:35:16 -070011885/*[clinic input]
11886os.startfile
11887 filepath: path_t
11888 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011889
Steve Dowercc16be82016-09-08 10:35:16 -070011890Start a file with its associated application.
11891
11892When "operation" is not specified or "open", this acts like
11893double-clicking the file in Explorer, or giving the file name as an
11894argument to the DOS "start" command: the file is opened with whatever
11895application (if any) its extension is associated.
11896When another "operation" is given, it specifies what should be done with
11897the file. A typical operation is "print".
11898
11899startfile returns as soon as the associated application is launched.
11900There is no option to wait for the application to close, and no way
11901to retrieve the application's exit status.
11902
11903The filepath is relative to the current directory. If you want to use
11904an absolute path, make sure the first character is not a slash ("/");
11905the underlying Win32 ShellExecute function doesn't work if it is.
11906[clinic start generated code]*/
11907
11908static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011909os_startfile_impl(PyObject *module, path_t *filepath,
11910 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030011911/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011912{
11913 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011914
11915 if(!check_ShellExecute()) {
11916 /* If the OS doesn't have ShellExecute, return a
11917 NotImplementedError. */
11918 return PyErr_Format(PyExc_NotImplementedError,
11919 "startfile not available on this platform");
11920 }
11921
Saiyang Gou7514f4f2020-02-12 23:47:42 -080011922 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080011923 return NULL;
11924 }
11925
Victor Stinner8c62be82010-05-06 00:08:46 +000011926 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011927 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011928 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011929 Py_END_ALLOW_THREADS
11930
Victor Stinner8c62be82010-05-06 00:08:46 +000011931 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011932 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011933 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011934 }
Steve Dowercc16be82016-09-08 10:35:16 -070011935 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011936}
Larry Hastings2f936352014-08-05 14:04:04 +100011937#endif /* MS_WINDOWS */
11938
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011939
Martin v. Löwis438b5342002-12-27 10:16:42 +000011940#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011941/*[clinic input]
11942os.getloadavg
11943
11944Return average recent system load information.
11945
11946Return the number of processes in the system run queue averaged over
11947the last 1, 5, and 15 minutes as a tuple of three floats.
11948Raises OSError if the load average was unobtainable.
11949[clinic start generated code]*/
11950
Larry Hastings2f936352014-08-05 14:04:04 +100011951static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011952os_getloadavg_impl(PyObject *module)
11953/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011954{
11955 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011956 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011957 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11958 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011959 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011960 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011961}
Larry Hastings2f936352014-08-05 14:04:04 +100011962#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011963
Larry Hastings2f936352014-08-05 14:04:04 +100011964
11965/*[clinic input]
11966os.device_encoding
11967 fd: int
11968
11969Return a string describing the encoding of a terminal's file descriptor.
11970
11971The file descriptor must be attached to a terminal.
11972If the device is not a terminal, return None.
11973[clinic start generated code]*/
11974
Larry Hastings2f936352014-08-05 14:04:04 +100011975static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011976os_device_encoding_impl(PyObject *module, int fd)
11977/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011978{
Brett Cannonefb00c02012-02-29 18:31:31 -050011979 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000011980}
11981
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011982
Larry Hastings2f936352014-08-05 14:04:04 +100011983#ifdef HAVE_SETRESUID
11984/*[clinic input]
11985os.setresuid
11986
11987 ruid: uid_t
11988 euid: uid_t
11989 suid: uid_t
11990 /
11991
11992Set the current process's real, effective, and saved user ids.
11993[clinic start generated code]*/
11994
Larry Hastings2f936352014-08-05 14:04:04 +100011995static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011996os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
11997/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011998{
Victor Stinner8c62be82010-05-06 00:08:46 +000011999 if (setresuid(ruid, euid, suid) < 0)
12000 return posix_error();
12001 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012002}
Larry Hastings2f936352014-08-05 14:04:04 +100012003#endif /* HAVE_SETRESUID */
12004
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012005
12006#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012007/*[clinic input]
12008os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012009
Larry Hastings2f936352014-08-05 14:04:04 +100012010 rgid: gid_t
12011 egid: gid_t
12012 sgid: gid_t
12013 /
12014
12015Set the current process's real, effective, and saved group ids.
12016[clinic start generated code]*/
12017
Larry Hastings2f936352014-08-05 14:04:04 +100012018static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012019os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12020/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012021{
Victor Stinner8c62be82010-05-06 00:08:46 +000012022 if (setresgid(rgid, egid, sgid) < 0)
12023 return posix_error();
12024 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012025}
Larry Hastings2f936352014-08-05 14:04:04 +100012026#endif /* HAVE_SETRESGID */
12027
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012028
12029#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012030/*[clinic input]
12031os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012032
Larry Hastings2f936352014-08-05 14:04:04 +100012033Return a tuple of the current process's real, effective, and saved user ids.
12034[clinic start generated code]*/
12035
Larry Hastings2f936352014-08-05 14:04:04 +100012036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012037os_getresuid_impl(PyObject *module)
12038/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012039{
Victor Stinner8c62be82010-05-06 00:08:46 +000012040 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012041 if (getresuid(&ruid, &euid, &suid) < 0)
12042 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012043 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12044 _PyLong_FromUid(euid),
12045 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012046}
Larry Hastings2f936352014-08-05 14:04:04 +100012047#endif /* HAVE_GETRESUID */
12048
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012049
12050#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012051/*[clinic input]
12052os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012053
Larry Hastings2f936352014-08-05 14:04:04 +100012054Return a tuple of the current process's real, effective, and saved group ids.
12055[clinic start generated code]*/
12056
Larry Hastings2f936352014-08-05 14:04:04 +100012057static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012058os_getresgid_impl(PyObject *module)
12059/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012060{
12061 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012062 if (getresgid(&rgid, &egid, &sgid) < 0)
12063 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012064 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12065 _PyLong_FromGid(egid),
12066 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012067}
Larry Hastings2f936352014-08-05 14:04:04 +100012068#endif /* HAVE_GETRESGID */
12069
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012070
Benjamin Peterson9428d532011-09-14 11:45:52 -040012071#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012072/*[clinic input]
12073os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012074
Larry Hastings2f936352014-08-05 14:04:04 +100012075 path: path_t(allow_fd=True)
12076 attribute: path_t
12077 *
12078 follow_symlinks: bool = True
12079
12080Return the value of extended attribute attribute on path.
12081
BNMetricsb9427072018-11-02 15:20:19 +000012082path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012083If follow_symlinks is False, and the last element of the path is a symbolic
12084 link, getxattr will examine the symbolic link itself instead of the file
12085 the link points to.
12086
12087[clinic start generated code]*/
12088
Larry Hastings2f936352014-08-05 14:04:04 +100012089static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012090os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012091 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012092/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012093{
12094 Py_ssize_t i;
12095 PyObject *buffer = NULL;
12096
12097 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12098 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012099
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012100 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12101 return NULL;
12102 }
12103
Larry Hastings9cf065c2012-06-22 16:30:09 -070012104 for (i = 0; ; i++) {
12105 void *ptr;
12106 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012107 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012108 Py_ssize_t buffer_size = buffer_sizes[i];
12109 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012110 path_error(path);
12111 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012112 }
12113 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12114 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012115 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012116 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012117
Larry Hastings9cf065c2012-06-22 16:30:09 -070012118 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012119 if (path->fd >= 0)
12120 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012121 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012122 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012123 else
Larry Hastings2f936352014-08-05 14:04:04 +100012124 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012125 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012126
Larry Hastings9cf065c2012-06-22 16:30:09 -070012127 if (result < 0) {
12128 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012129 if (errno == ERANGE)
12130 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012131 path_error(path);
12132 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012133 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012134
Larry Hastings9cf065c2012-06-22 16:30:09 -070012135 if (result != buffer_size) {
12136 /* Can only shrink. */
12137 _PyBytes_Resize(&buffer, result);
12138 }
12139 break;
12140 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012141
Larry Hastings9cf065c2012-06-22 16:30:09 -070012142 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012143}
12144
Larry Hastings2f936352014-08-05 14:04:04 +100012145
12146/*[clinic input]
12147os.setxattr
12148
12149 path: path_t(allow_fd=True)
12150 attribute: path_t
12151 value: Py_buffer
12152 flags: int = 0
12153 *
12154 follow_symlinks: bool = True
12155
12156Set extended attribute attribute on path to value.
12157
BNMetricsb9427072018-11-02 15:20:19 +000012158path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012159If follow_symlinks is False, and the last element of the path is a symbolic
12160 link, setxattr will modify the symbolic link itself instead of the file
12161 the link points to.
12162
12163[clinic start generated code]*/
12164
Benjamin Peterson799bd802011-08-31 22:15:17 -040012165static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012166os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012167 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012168/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012169{
Larry Hastings2f936352014-08-05 14:04:04 +100012170 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012171
Larry Hastings2f936352014-08-05 14:04:04 +100012172 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012173 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012174
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012175 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12176 value->buf, value->len, flags) < 0) {
12177 return NULL;
12178 }
12179
Benjamin Peterson799bd802011-08-31 22:15:17 -040012180 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012181 if (path->fd > -1)
12182 result = fsetxattr(path->fd, attribute->narrow,
12183 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012184 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012185 result = setxattr(path->narrow, attribute->narrow,
12186 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012187 else
Larry Hastings2f936352014-08-05 14:04:04 +100012188 result = lsetxattr(path->narrow, attribute->narrow,
12189 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012190 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012191
Larry Hastings9cf065c2012-06-22 16:30:09 -070012192 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012193 path_error(path);
12194 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012195 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012196
Larry Hastings2f936352014-08-05 14:04:04 +100012197 Py_RETURN_NONE;
12198}
12199
12200
12201/*[clinic input]
12202os.removexattr
12203
12204 path: path_t(allow_fd=True)
12205 attribute: path_t
12206 *
12207 follow_symlinks: bool = True
12208
12209Remove extended attribute attribute on path.
12210
BNMetricsb9427072018-11-02 15:20:19 +000012211path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012212If follow_symlinks is False, and the last element of the path is a symbolic
12213 link, removexattr will modify the symbolic link itself instead of the file
12214 the link points to.
12215
12216[clinic start generated code]*/
12217
Larry Hastings2f936352014-08-05 14:04:04 +100012218static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012219os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012220 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012221/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012222{
12223 ssize_t result;
12224
12225 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12226 return NULL;
12227
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012228 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12229 return NULL;
12230 }
12231
Larry Hastings2f936352014-08-05 14:04:04 +100012232 Py_BEGIN_ALLOW_THREADS;
12233 if (path->fd > -1)
12234 result = fremovexattr(path->fd, attribute->narrow);
12235 else if (follow_symlinks)
12236 result = removexattr(path->narrow, attribute->narrow);
12237 else
12238 result = lremovexattr(path->narrow, attribute->narrow);
12239 Py_END_ALLOW_THREADS;
12240
12241 if (result) {
12242 return path_error(path);
12243 }
12244
12245 Py_RETURN_NONE;
12246}
12247
12248
12249/*[clinic input]
12250os.listxattr
12251
12252 path: path_t(allow_fd=True, nullable=True) = None
12253 *
12254 follow_symlinks: bool = True
12255
12256Return a list of extended attributes on path.
12257
BNMetricsb9427072018-11-02 15:20:19 +000012258path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012259if path is None, listxattr will examine the current directory.
12260If follow_symlinks is False, and the last element of the path is a symbolic
12261 link, listxattr will examine the symbolic link itself instead of the file
12262 the link points to.
12263[clinic start generated code]*/
12264
Larry Hastings2f936352014-08-05 14:04:04 +100012265static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012266os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012267/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012268{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012269 Py_ssize_t i;
12270 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012271 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012272 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012273
Larry Hastings2f936352014-08-05 14:04:04 +100012274 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012275 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012276
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012277 if (PySys_Audit("os.listxattr", "(O)",
12278 path->object ? path->object : Py_None) < 0) {
12279 return NULL;
12280 }
12281
Larry Hastings2f936352014-08-05 14:04:04 +100012282 name = path->narrow ? path->narrow : ".";
12283
Larry Hastings9cf065c2012-06-22 16:30:09 -070012284 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012285 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012286 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012287 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012288 Py_ssize_t buffer_size = buffer_sizes[i];
12289 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012290 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012291 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012292 break;
12293 }
12294 buffer = PyMem_MALLOC(buffer_size);
12295 if (!buffer) {
12296 PyErr_NoMemory();
12297 break;
12298 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012299
Larry Hastings9cf065c2012-06-22 16:30:09 -070012300 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012301 if (path->fd > -1)
12302 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012303 else if (follow_symlinks)
12304 length = listxattr(name, buffer, buffer_size);
12305 else
12306 length = llistxattr(name, buffer, buffer_size);
12307 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012308
Larry Hastings9cf065c2012-06-22 16:30:09 -070012309 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012310 if (errno == ERANGE) {
12311 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012312 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012313 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012314 }
Larry Hastings2f936352014-08-05 14:04:04 +100012315 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012316 break;
12317 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012318
Larry Hastings9cf065c2012-06-22 16:30:09 -070012319 result = PyList_New(0);
12320 if (!result) {
12321 goto exit;
12322 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012323
Larry Hastings9cf065c2012-06-22 16:30:09 -070012324 end = buffer + length;
12325 for (trace = start = buffer; trace != end; trace++) {
12326 if (!*trace) {
12327 int error;
12328 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12329 trace - start);
12330 if (!attribute) {
12331 Py_DECREF(result);
12332 result = NULL;
12333 goto exit;
12334 }
12335 error = PyList_Append(result, attribute);
12336 Py_DECREF(attribute);
12337 if (error) {
12338 Py_DECREF(result);
12339 result = NULL;
12340 goto exit;
12341 }
12342 start = trace + 1;
12343 }
12344 }
12345 break;
12346 }
12347exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012348 if (buffer)
12349 PyMem_FREE(buffer);
12350 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012351}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012352#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012353
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012354
Larry Hastings2f936352014-08-05 14:04:04 +100012355/*[clinic input]
12356os.urandom
12357
12358 size: Py_ssize_t
12359 /
12360
12361Return a bytes object containing random bytes suitable for cryptographic use.
12362[clinic start generated code]*/
12363
Larry Hastings2f936352014-08-05 14:04:04 +100012364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012365os_urandom_impl(PyObject *module, Py_ssize_t size)
12366/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012367{
12368 PyObject *bytes;
12369 int result;
12370
Georg Brandl2fb477c2012-02-21 00:33:36 +010012371 if (size < 0)
12372 return PyErr_Format(PyExc_ValueError,
12373 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012374 bytes = PyBytes_FromStringAndSize(NULL, size);
12375 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012376 return NULL;
12377
Victor Stinnere66987e2016-09-06 16:33:52 -070012378 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012379 if (result == -1) {
12380 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012381 return NULL;
12382 }
Larry Hastings2f936352014-08-05 14:04:04 +100012383 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012384}
12385
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012386#ifdef HAVE_MEMFD_CREATE
12387/*[clinic input]
12388os.memfd_create
12389
12390 name: FSConverter
12391 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12392
12393[clinic start generated code]*/
12394
12395static PyObject *
12396os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12397/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12398{
12399 int fd;
12400 const char *bytes = PyBytes_AS_STRING(name);
12401 Py_BEGIN_ALLOW_THREADS
12402 fd = memfd_create(bytes, flags);
12403 Py_END_ALLOW_THREADS
12404 if (fd == -1) {
12405 return PyErr_SetFromErrno(PyExc_OSError);
12406 }
12407 return PyLong_FromLong(fd);
12408}
12409#endif
12410
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012411/* Terminal size querying */
12412
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012413PyDoc_STRVAR(TerminalSize_docstring,
12414 "A tuple of (columns, lines) for holding terminal window size");
12415
12416static PyStructSequence_Field TerminalSize_fields[] = {
12417 {"columns", "width of the terminal window in characters"},
12418 {"lines", "height of the terminal window in characters"},
12419 {NULL, NULL}
12420};
12421
12422static PyStructSequence_Desc TerminalSize_desc = {
12423 "os.terminal_size",
12424 TerminalSize_docstring,
12425 TerminalSize_fields,
12426 2,
12427};
12428
12429#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012430/*[clinic input]
12431os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012432
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012433 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
12434 /
12435
12436Return the size of the terminal window as (columns, lines).
12437
12438The optional argument fd (default standard output) specifies
12439which file descriptor should be queried.
12440
12441If the file descriptor is not connected to a terminal, an OSError
12442is thrown.
12443
12444This function will only be defined if an implementation is
12445available for this system.
12446
12447shutil.get_terminal_size is the high-level function which should
12448normally be used, os.get_terminal_size is the low-level implementation.
12449[clinic start generated code]*/
12450
12451static PyObject *
12452os_get_terminal_size_impl(PyObject *module, int fd)
12453/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012454{
12455 int columns, lines;
12456 PyObject *termsize;
12457
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012458 /* Under some conditions stdout may not be connected and
12459 * fileno(stdout) may point to an invalid file descriptor. For example
12460 * GUI apps don't have valid standard streams by default.
12461 *
12462 * If this happens, and the optional fd argument is not present,
12463 * the ioctl below will fail returning EBADF. This is what we want.
12464 */
12465
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012466#ifdef TERMSIZE_USE_IOCTL
12467 {
12468 struct winsize w;
12469 if (ioctl(fd, TIOCGWINSZ, &w))
12470 return PyErr_SetFromErrno(PyExc_OSError);
12471 columns = w.ws_col;
12472 lines = w.ws_row;
12473 }
12474#endif /* TERMSIZE_USE_IOCTL */
12475
12476#ifdef TERMSIZE_USE_CONIO
12477 {
12478 DWORD nhandle;
12479 HANDLE handle;
12480 CONSOLE_SCREEN_BUFFER_INFO csbi;
12481 switch (fd) {
12482 case 0: nhandle = STD_INPUT_HANDLE;
12483 break;
12484 case 1: nhandle = STD_OUTPUT_HANDLE;
12485 break;
12486 case 2: nhandle = STD_ERROR_HANDLE;
12487 break;
12488 default:
12489 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12490 }
12491 handle = GetStdHandle(nhandle);
12492 if (handle == NULL)
12493 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12494 if (handle == INVALID_HANDLE_VALUE)
12495 return PyErr_SetFromWindowsErr(0);
12496
12497 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12498 return PyErr_SetFromWindowsErr(0);
12499
12500 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12501 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12502 }
12503#endif /* TERMSIZE_USE_CONIO */
12504
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012505 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080012506 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012507 if (termsize == NULL)
12508 return NULL;
12509 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12510 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12511 if (PyErr_Occurred()) {
12512 Py_DECREF(termsize);
12513 return NULL;
12514 }
12515 return termsize;
12516}
12517#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12518
Larry Hastings2f936352014-08-05 14:04:04 +100012519
12520/*[clinic input]
12521os.cpu_count
12522
Charles-François Natali80d62e62015-08-13 20:37:08 +010012523Return the number of CPUs in the system; return None if indeterminable.
12524
12525This number is not equivalent to the number of CPUs the current process can
12526use. The number of usable CPUs can be obtained with
12527``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012528[clinic start generated code]*/
12529
Larry Hastings2f936352014-08-05 14:04:04 +100012530static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012531os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012532/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012533{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012534 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012535#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010012536 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012537#elif defined(__hpux)
12538 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12539#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12540 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012541#elif defined(__DragonFly__) || \
12542 defined(__OpenBSD__) || \
12543 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012544 defined(__NetBSD__) || \
12545 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012546 int mib[2];
12547 size_t len = sizeof(ncpu);
12548 mib[0] = CTL_HW;
12549 mib[1] = HW_NCPU;
12550 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12551 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012552#endif
12553 if (ncpu >= 1)
12554 return PyLong_FromLong(ncpu);
12555 else
12556 Py_RETURN_NONE;
12557}
12558
Victor Stinnerdaf45552013-08-28 00:53:59 +020012559
Larry Hastings2f936352014-08-05 14:04:04 +100012560/*[clinic input]
12561os.get_inheritable -> bool
12562
12563 fd: int
12564 /
12565
12566Get the close-on-exe flag of the specified file descriptor.
12567[clinic start generated code]*/
12568
Larry Hastings2f936352014-08-05 14:04:04 +100012569static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012570os_get_inheritable_impl(PyObject *module, int fd)
12571/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012572{
Steve Dower8fc89802015-04-12 00:26:27 -040012573 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012574 _Py_BEGIN_SUPPRESS_IPH
12575 return_value = _Py_get_inheritable(fd);
12576 _Py_END_SUPPRESS_IPH
12577 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012578}
12579
12580
12581/*[clinic input]
12582os.set_inheritable
12583 fd: int
12584 inheritable: int
12585 /
12586
12587Set the inheritable flag of the specified file descriptor.
12588[clinic start generated code]*/
12589
Larry Hastings2f936352014-08-05 14:04:04 +100012590static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012591os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12592/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012593{
Steve Dower8fc89802015-04-12 00:26:27 -040012594 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012595
Steve Dower8fc89802015-04-12 00:26:27 -040012596 _Py_BEGIN_SUPPRESS_IPH
12597 result = _Py_set_inheritable(fd, inheritable, NULL);
12598 _Py_END_SUPPRESS_IPH
12599 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012600 return NULL;
12601 Py_RETURN_NONE;
12602}
12603
12604
12605#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012606/*[clinic input]
12607os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012608 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012609 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012610
Larry Hastings2f936352014-08-05 14:04:04 +100012611Get the close-on-exe flag of the specified file descriptor.
12612[clinic start generated code]*/
12613
Larry Hastings2f936352014-08-05 14:04:04 +100012614static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012615os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012616/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012617{
12618 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012619
12620 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12621 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012622 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012623 }
12624
Larry Hastings2f936352014-08-05 14:04:04 +100012625 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012626}
12627
Victor Stinnerdaf45552013-08-28 00:53:59 +020012628
Larry Hastings2f936352014-08-05 14:04:04 +100012629/*[clinic input]
12630os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012631 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012632 inheritable: bool
12633 /
12634
12635Set the inheritable flag of the specified handle.
12636[clinic start generated code]*/
12637
Larry Hastings2f936352014-08-05 14:04:04 +100012638static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012639os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012640 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012641/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012642{
12643 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012644 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12645 PyErr_SetFromWindowsErr(0);
12646 return NULL;
12647 }
12648 Py_RETURN_NONE;
12649}
Larry Hastings2f936352014-08-05 14:04:04 +100012650#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012651
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012652#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012653/*[clinic input]
12654os.get_blocking -> bool
12655 fd: int
12656 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012657
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012658Get the blocking mode of the file descriptor.
12659
12660Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12661[clinic start generated code]*/
12662
12663static int
12664os_get_blocking_impl(PyObject *module, int fd)
12665/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012666{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012667 int blocking;
12668
Steve Dower8fc89802015-04-12 00:26:27 -040012669 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012670 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012671 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012672 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012673}
12674
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012675/*[clinic input]
12676os.set_blocking
12677 fd: int
12678 blocking: bool(accept={int})
12679 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012680
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012681Set the blocking mode of the specified file descriptor.
12682
12683Set the O_NONBLOCK flag if blocking is False,
12684clear the O_NONBLOCK flag otherwise.
12685[clinic start generated code]*/
12686
12687static PyObject *
12688os_set_blocking_impl(PyObject *module, int fd, int blocking)
12689/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012690{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012691 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012692
Steve Dower8fc89802015-04-12 00:26:27 -040012693 _Py_BEGIN_SUPPRESS_IPH
12694 result = _Py_set_blocking(fd, blocking);
12695 _Py_END_SUPPRESS_IPH
12696 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012697 return NULL;
12698 Py_RETURN_NONE;
12699}
12700#endif /* !MS_WINDOWS */
12701
12702
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012703/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080012704class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012705[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080012706/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012707
12708typedef struct {
12709 PyObject_HEAD
12710 PyObject *name;
12711 PyObject *path;
12712 PyObject *stat;
12713 PyObject *lstat;
12714#ifdef MS_WINDOWS
12715 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012716 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012717 int got_file_index;
12718#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012719#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012720 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012721#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012722 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012723 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012724#endif
12725} DirEntry;
12726
Eddie Elizondob3966632019-11-05 07:16:14 -080012727static PyObject *
12728_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
12729{
12730 PyErr_Format(PyExc_TypeError,
12731 "cannot create '%.100s' instances", _PyType_Name(type));
12732 return NULL;
12733}
12734
Victor Stinner6036e442015-03-08 01:58:04 +010012735static void
12736DirEntry_dealloc(DirEntry *entry)
12737{
Eddie Elizondob3966632019-11-05 07:16:14 -080012738 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010012739 Py_XDECREF(entry->name);
12740 Py_XDECREF(entry->path);
12741 Py_XDECREF(entry->stat);
12742 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080012743 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
12744 free_func(entry);
12745 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010012746}
12747
12748/* Forward reference */
12749static int
12750DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12751
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012752/*[clinic input]
12753os.DirEntry.is_symlink -> bool
12754
12755Return True if the entry is a symbolic link; cached per entry.
12756[clinic start generated code]*/
12757
Victor Stinner6036e442015-03-08 01:58:04 +010012758static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012759os_DirEntry_is_symlink_impl(DirEntry *self)
12760/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012761{
12762#ifdef MS_WINDOWS
12763 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012764#elif defined(HAVE_DIRENT_D_TYPE)
12765 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012766 if (self->d_type != DT_UNKNOWN)
12767 return self->d_type == DT_LNK;
12768 else
12769 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012770#else
12771 /* POSIX without d_type */
12772 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012773#endif
12774}
12775
Victor Stinner1c2fa782020-05-10 11:05:29 +020012776static inline PyObject*
12777DirEntry_get_module(DirEntry *self)
12778{
12779 return PyType_GetModule(Py_TYPE(self));
12780}
12781
Victor Stinner6036e442015-03-08 01:58:04 +010012782static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010012783DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12784{
12785 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012786 STRUCT_STAT st;
12787 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012788
12789#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012790 if (!PyUnicode_FSDecoder(self->path, &ub))
12791 return NULL;
12792 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012793#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012794 if (!PyUnicode_FSConverter(self->path, &ub))
12795 return NULL;
12796 const char *path = PyBytes_AS_STRING(ub);
12797 if (self->dir_fd != DEFAULT_DIR_FD) {
12798#ifdef HAVE_FSTATAT
12799 result = fstatat(self->dir_fd, path, &st,
12800 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12801#else
12802 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12803 return NULL;
12804#endif /* HAVE_FSTATAT */
12805 }
12806 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012807#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012808 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012809 if (follow_symlinks)
12810 result = STAT(path, &st);
12811 else
12812 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012813 }
12814 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012815
12816 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012817 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012818
Victor Stinner1c2fa782020-05-10 11:05:29 +020012819 return _pystat_fromstructstat(DirEntry_get_module(self), &st);
Victor Stinner6036e442015-03-08 01:58:04 +010012820}
12821
12822static PyObject *
12823DirEntry_get_lstat(DirEntry *self)
12824{
12825 if (!self->lstat) {
12826#ifdef MS_WINDOWS
Victor Stinner1c2fa782020-05-10 11:05:29 +020012827 self->lstat = _pystat_fromstructstat(DirEntry_get_module(self),
12828 &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010012829#else /* POSIX */
12830 self->lstat = DirEntry_fetch_stat(self, 0);
12831#endif
12832 }
12833 Py_XINCREF(self->lstat);
12834 return self->lstat;
12835}
12836
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012837/*[clinic input]
12838os.DirEntry.stat
12839 *
12840 follow_symlinks: bool = True
12841
12842Return stat_result object for the entry; cached per entry.
12843[clinic start generated code]*/
12844
Victor Stinner6036e442015-03-08 01:58:04 +010012845static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012846os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12847/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012848{
12849 if (!follow_symlinks)
12850 return DirEntry_get_lstat(self);
12851
12852 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012853 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010012854 if (result == -1)
12855 return NULL;
12856 else if (result)
12857 self->stat = DirEntry_fetch_stat(self, 1);
12858 else
12859 self->stat = DirEntry_get_lstat(self);
12860 }
12861
12862 Py_XINCREF(self->stat);
12863 return self->stat;
12864}
12865
Victor Stinner6036e442015-03-08 01:58:04 +010012866/* Set exception and return -1 on error, 0 for False, 1 for True */
12867static int
12868DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12869{
12870 PyObject *stat = NULL;
12871 PyObject *st_mode = NULL;
12872 long mode;
12873 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012874#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012875 int is_symlink;
12876 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012877#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012878#ifdef MS_WINDOWS
12879 unsigned long dir_bits;
12880#endif
12881
12882#ifdef MS_WINDOWS
12883 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12884 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012885#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012886 is_symlink = self->d_type == DT_LNK;
12887 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12888#endif
12889
Victor Stinner35a97c02015-03-08 02:59:09 +010012890#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012891 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012892#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012893 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012894 if (!stat) {
12895 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12896 /* If file doesn't exist (anymore), then return False
12897 (i.e., say it's not a file/directory) */
12898 PyErr_Clear();
12899 return 0;
12900 }
12901 goto error;
12902 }
Victor Stinner1c2fa782020-05-10 11:05:29 +020012903 st_mode = PyObject_GetAttr(stat, get_posix_state(DirEntry_get_module(self))->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012904 if (!st_mode)
12905 goto error;
12906
12907 mode = PyLong_AsLong(st_mode);
12908 if (mode == -1 && PyErr_Occurred())
12909 goto error;
12910 Py_CLEAR(st_mode);
12911 Py_CLEAR(stat);
12912 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012913#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012914 }
12915 else if (is_symlink) {
12916 assert(mode_bits != S_IFLNK);
12917 result = 0;
12918 }
12919 else {
12920 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12921#ifdef MS_WINDOWS
12922 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12923 if (mode_bits == S_IFDIR)
12924 result = dir_bits != 0;
12925 else
12926 result = dir_bits == 0;
12927#else /* POSIX */
12928 if (mode_bits == S_IFDIR)
12929 result = self->d_type == DT_DIR;
12930 else
12931 result = self->d_type == DT_REG;
12932#endif
12933 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012934#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012935
12936 return result;
12937
12938error:
12939 Py_XDECREF(st_mode);
12940 Py_XDECREF(stat);
12941 return -1;
12942}
12943
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012944/*[clinic input]
12945os.DirEntry.is_dir -> bool
12946 *
12947 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012948
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012949Return True if the entry is a directory; cached per entry.
12950[clinic start generated code]*/
12951
12952static int
12953os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12954/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12955{
12956 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012957}
12958
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012959/*[clinic input]
12960os.DirEntry.is_file -> bool
12961 *
12962 follow_symlinks: bool = True
12963
12964Return True if the entry is a file; cached per entry.
12965[clinic start generated code]*/
12966
12967static int
12968os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12969/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012970{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012971 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010012972}
12973
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012974/*[clinic input]
12975os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010012976
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012977Return inode of the entry; cached per entry.
12978[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012979
12980static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012981os_DirEntry_inode_impl(DirEntry *self)
12982/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012983{
12984#ifdef MS_WINDOWS
12985 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012986 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012987 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012988 STRUCT_STAT stat;
12989 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010012990
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012991 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010012992 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012993 path = PyUnicode_AsUnicode(unicode);
12994 result = LSTAT(path, &stat);
12995 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010012996
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012997 if (result != 0)
12998 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012999
13000 self->win32_file_index = stat.st_ino;
13001 self->got_file_index = 1;
13002 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013003 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13004 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013005#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013006 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13007 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013008#endif
13009}
13010
13011static PyObject *
13012DirEntry_repr(DirEntry *self)
13013{
13014 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13015}
13016
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013017/*[clinic input]
13018os.DirEntry.__fspath__
13019
13020Returns the path for the entry.
13021[clinic start generated code]*/
13022
Brett Cannon96881cd2016-06-10 14:37:21 -070013023static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013024os_DirEntry___fspath___impl(DirEntry *self)
13025/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013026{
13027 Py_INCREF(self->path);
13028 return self->path;
13029}
13030
Victor Stinner6036e442015-03-08 01:58:04 +010013031static PyMemberDef DirEntry_members[] = {
13032 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13033 "the entry's base filename, relative to scandir() \"path\" argument"},
13034 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13035 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13036 {NULL}
13037};
13038
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013039#include "clinic/posixmodule.c.h"
13040
Victor Stinner6036e442015-03-08 01:58:04 +010013041static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013042 OS_DIRENTRY_IS_DIR_METHODDEF
13043 OS_DIRENTRY_IS_FILE_METHODDEF
13044 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13045 OS_DIRENTRY_STAT_METHODDEF
13046 OS_DIRENTRY_INODE_METHODDEF
13047 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013048 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13049 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013050 {NULL}
13051};
13052
Eddie Elizondob3966632019-11-05 07:16:14 -080013053static PyType_Slot DirEntryType_slots[] = {
13054 {Py_tp_new, _disabled_new},
13055 {Py_tp_dealloc, DirEntry_dealloc},
13056 {Py_tp_repr, DirEntry_repr},
13057 {Py_tp_methods, DirEntry_methods},
13058 {Py_tp_members, DirEntry_members},
13059 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013060};
13061
Eddie Elizondob3966632019-11-05 07:16:14 -080013062static PyType_Spec DirEntryType_spec = {
13063 MODNAME ".DirEntry",
13064 sizeof(DirEntry),
13065 0,
13066 Py_TPFLAGS_DEFAULT,
13067 DirEntryType_slots
13068};
13069
13070
Victor Stinner6036e442015-03-08 01:58:04 +010013071#ifdef MS_WINDOWS
13072
13073static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013074join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013075{
13076 Py_ssize_t path_len;
13077 Py_ssize_t size;
13078 wchar_t *result;
13079 wchar_t ch;
13080
13081 if (!path_wide) { /* Default arg: "." */
13082 path_wide = L".";
13083 path_len = 1;
13084 }
13085 else {
13086 path_len = wcslen(path_wide);
13087 }
13088
13089 /* The +1's are for the path separator and the NUL */
13090 size = path_len + 1 + wcslen(filename) + 1;
13091 result = PyMem_New(wchar_t, size);
13092 if (!result) {
13093 PyErr_NoMemory();
13094 return NULL;
13095 }
13096 wcscpy(result, path_wide);
13097 if (path_len > 0) {
13098 ch = result[path_len - 1];
13099 if (ch != SEP && ch != ALTSEP && ch != L':')
13100 result[path_len++] = SEP;
13101 wcscpy(result + path_len, filename);
13102 }
13103 return result;
13104}
13105
13106static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013107DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013108{
13109 DirEntry *entry;
13110 BY_HANDLE_FILE_INFORMATION file_info;
13111 ULONG reparse_tag;
13112 wchar_t *joined_path;
13113
Victor Stinner1c2fa782020-05-10 11:05:29 +020013114 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013115 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013116 if (!entry)
13117 return NULL;
13118 entry->name = NULL;
13119 entry->path = NULL;
13120 entry->stat = NULL;
13121 entry->lstat = NULL;
13122 entry->got_file_index = 0;
13123
13124 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13125 if (!entry->name)
13126 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013127 if (path->narrow) {
13128 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13129 if (!entry->name)
13130 goto error;
13131 }
Victor Stinner6036e442015-03-08 01:58:04 +010013132
13133 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13134 if (!joined_path)
13135 goto error;
13136
13137 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13138 PyMem_Free(joined_path);
13139 if (!entry->path)
13140 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013141 if (path->narrow) {
13142 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13143 if (!entry->path)
13144 goto error;
13145 }
Victor Stinner6036e442015-03-08 01:58:04 +010013146
Steve Dowercc16be82016-09-08 10:35:16 -070013147 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013148 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13149
13150 return (PyObject *)entry;
13151
13152error:
13153 Py_DECREF(entry);
13154 return NULL;
13155}
13156
13157#else /* POSIX */
13158
13159static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013160join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013161{
13162 Py_ssize_t path_len;
13163 Py_ssize_t size;
13164 char *result;
13165
13166 if (!path_narrow) { /* Default arg: "." */
13167 path_narrow = ".";
13168 path_len = 1;
13169 }
13170 else {
13171 path_len = strlen(path_narrow);
13172 }
13173
13174 if (filename_len == -1)
13175 filename_len = strlen(filename);
13176
13177 /* The +1's are for the path separator and the NUL */
13178 size = path_len + 1 + filename_len + 1;
13179 result = PyMem_New(char, size);
13180 if (!result) {
13181 PyErr_NoMemory();
13182 return NULL;
13183 }
13184 strcpy(result, path_narrow);
13185 if (path_len > 0 && result[path_len - 1] != '/')
13186 result[path_len++] = '/';
13187 strcpy(result + path_len, filename);
13188 return result;
13189}
13190
13191static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013192DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13193 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013194#ifdef HAVE_DIRENT_D_TYPE
13195 , unsigned char d_type
13196#endif
13197 )
Victor Stinner6036e442015-03-08 01:58:04 +010013198{
13199 DirEntry *entry;
13200 char *joined_path;
13201
Victor Stinner1c2fa782020-05-10 11:05:29 +020013202 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013203 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013204 if (!entry)
13205 return NULL;
13206 entry->name = NULL;
13207 entry->path = NULL;
13208 entry->stat = NULL;
13209 entry->lstat = NULL;
13210
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013211 if (path->fd != -1) {
13212 entry->dir_fd = path->fd;
13213 joined_path = NULL;
13214 }
13215 else {
13216 entry->dir_fd = DEFAULT_DIR_FD;
13217 joined_path = join_path_filename(path->narrow, name, name_len);
13218 if (!joined_path)
13219 goto error;
13220 }
Victor Stinner6036e442015-03-08 01:58:04 +010013221
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013222 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013223 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013224 if (joined_path)
13225 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013226 }
13227 else {
13228 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013229 if (joined_path)
13230 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013231 }
13232 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013233 if (!entry->name)
13234 goto error;
13235
13236 if (path->fd != -1) {
13237 entry->path = entry->name;
13238 Py_INCREF(entry->path);
13239 }
13240 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013241 goto error;
13242
Victor Stinner35a97c02015-03-08 02:59:09 +010013243#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013244 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013245#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013246 entry->d_ino = d_ino;
13247
13248 return (PyObject *)entry;
13249
13250error:
13251 Py_XDECREF(entry);
13252 return NULL;
13253}
13254
13255#endif
13256
13257
13258typedef struct {
13259 PyObject_HEAD
13260 path_t path;
13261#ifdef MS_WINDOWS
13262 HANDLE handle;
13263 WIN32_FIND_DATAW file_data;
13264 int first_time;
13265#else /* POSIX */
13266 DIR *dirp;
13267#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013268#ifdef HAVE_FDOPENDIR
13269 int fd;
13270#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013271} ScandirIterator;
13272
13273#ifdef MS_WINDOWS
13274
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013275static int
13276ScandirIterator_is_closed(ScandirIterator *iterator)
13277{
13278 return iterator->handle == INVALID_HANDLE_VALUE;
13279}
13280
Victor Stinner6036e442015-03-08 01:58:04 +010013281static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013282ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013283{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013284 HANDLE handle = iterator->handle;
13285
13286 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013287 return;
13288
Victor Stinner6036e442015-03-08 01:58:04 +010013289 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013290 Py_BEGIN_ALLOW_THREADS
13291 FindClose(handle);
13292 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013293}
13294
13295static PyObject *
13296ScandirIterator_iternext(ScandirIterator *iterator)
13297{
13298 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13299 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013300 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013301
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013302 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013303 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013304 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013305
13306 while (1) {
13307 if (!iterator->first_time) {
13308 Py_BEGIN_ALLOW_THREADS
13309 success = FindNextFileW(iterator->handle, file_data);
13310 Py_END_ALLOW_THREADS
13311 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013312 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013313 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013314 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013315 break;
13316 }
13317 }
13318 iterator->first_time = 0;
13319
13320 /* Skip over . and .. */
13321 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020013322 wcscmp(file_data->cFileName, L"..") != 0)
13323 {
13324 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13325 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013326 if (!entry)
13327 break;
13328 return entry;
13329 }
Victor Stinner6036e442015-03-08 01:58:04 +010013330
13331 /* Loop till we get a non-dot directory or finish iterating */
13332 }
13333
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013334 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013335 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013336 return NULL;
13337}
13338
13339#else /* POSIX */
13340
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013341static int
13342ScandirIterator_is_closed(ScandirIterator *iterator)
13343{
13344 return !iterator->dirp;
13345}
13346
Victor Stinner6036e442015-03-08 01:58:04 +010013347static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013348ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013349{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013350 DIR *dirp = iterator->dirp;
13351
13352 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013353 return;
13354
Victor Stinner6036e442015-03-08 01:58:04 +010013355 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013356 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013357#ifdef HAVE_FDOPENDIR
13358 if (iterator->path.fd != -1)
13359 rewinddir(dirp);
13360#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013361 closedir(dirp);
13362 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013363 return;
13364}
13365
13366static PyObject *
13367ScandirIterator_iternext(ScandirIterator *iterator)
13368{
13369 struct dirent *direntp;
13370 Py_ssize_t name_len;
13371 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013372 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013373
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013374 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013375 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013376 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013377
13378 while (1) {
13379 errno = 0;
13380 Py_BEGIN_ALLOW_THREADS
13381 direntp = readdir(iterator->dirp);
13382 Py_END_ALLOW_THREADS
13383
13384 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013385 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013386 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013387 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013388 break;
13389 }
13390
13391 /* Skip over . and .. */
13392 name_len = NAMLEN(direntp);
13393 is_dot = direntp->d_name[0] == '.' &&
13394 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13395 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020013396 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13397 entry = DirEntry_from_posix_info(module,
13398 &iterator->path, direntp->d_name,
13399 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013400#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020013401 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010013402#endif
13403 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013404 if (!entry)
13405 break;
13406 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013407 }
13408
13409 /* Loop till we get a non-dot directory or finish iterating */
13410 }
13411
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013412 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013413 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013414 return NULL;
13415}
13416
13417#endif
13418
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013419static PyObject *
13420ScandirIterator_close(ScandirIterator *self, PyObject *args)
13421{
13422 ScandirIterator_closedir(self);
13423 Py_RETURN_NONE;
13424}
13425
13426static PyObject *
13427ScandirIterator_enter(PyObject *self, PyObject *args)
13428{
13429 Py_INCREF(self);
13430 return self;
13431}
13432
13433static PyObject *
13434ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13435{
13436 ScandirIterator_closedir(self);
13437 Py_RETURN_NONE;
13438}
13439
Victor Stinner6036e442015-03-08 01:58:04 +010013440static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013441ScandirIterator_finalize(ScandirIterator *iterator)
13442{
13443 PyObject *error_type, *error_value, *error_traceback;
13444
13445 /* Save the current exception, if any. */
13446 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13447
13448 if (!ScandirIterator_is_closed(iterator)) {
13449 ScandirIterator_closedir(iterator);
13450
13451 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13452 "unclosed scandir iterator %R", iterator)) {
13453 /* Spurious errors can appear at shutdown */
13454 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13455 PyErr_WriteUnraisable((PyObject *) iterator);
13456 }
13457 }
13458 }
13459
Victor Stinner7bfa4092016-03-23 00:43:54 +010013460 path_cleanup(&iterator->path);
13461
13462 /* Restore the saved exception. */
13463 PyErr_Restore(error_type, error_value, error_traceback);
13464}
13465
13466static void
Victor Stinner6036e442015-03-08 01:58:04 +010013467ScandirIterator_dealloc(ScandirIterator *iterator)
13468{
Eddie Elizondob3966632019-11-05 07:16:14 -080013469 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010013470 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13471 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013472
Eddie Elizondob3966632019-11-05 07:16:14 -080013473 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13474 free_func(iterator);
13475 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013476}
13477
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013478static PyMethodDef ScandirIterator_methods[] = {
13479 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13480 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13481 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13482 {NULL}
13483};
13484
Eddie Elizondob3966632019-11-05 07:16:14 -080013485static PyType_Slot ScandirIteratorType_slots[] = {
13486 {Py_tp_new, _disabled_new},
13487 {Py_tp_dealloc, ScandirIterator_dealloc},
13488 {Py_tp_finalize, ScandirIterator_finalize},
13489 {Py_tp_iter, PyObject_SelfIter},
13490 {Py_tp_iternext, ScandirIterator_iternext},
13491 {Py_tp_methods, ScandirIterator_methods},
13492 {0, 0},
13493};
13494
13495static PyType_Spec ScandirIteratorType_spec = {
13496 MODNAME ".ScandirIterator",
13497 sizeof(ScandirIterator),
13498 0,
13499 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
13500 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010013501};
13502
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013503/*[clinic input]
13504os.scandir
13505
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013506 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013507
13508Return an iterator of DirEntry objects for given path.
13509
BNMetricsb9427072018-11-02 15:20:19 +000013510path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013511is bytes, the names of yielded DirEntry objects will also be bytes; in
13512all other circumstances they will be str.
13513
13514If path is None, uses the path='.'.
13515[clinic start generated code]*/
13516
Victor Stinner6036e442015-03-08 01:58:04 +010013517static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013518os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013519/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013520{
13521 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013522#ifdef MS_WINDOWS
13523 wchar_t *path_strW;
13524#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013525 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013526#ifdef HAVE_FDOPENDIR
13527 int fd = -1;
13528#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013529#endif
13530
Steve Dower60419a72019-06-24 08:42:54 -070013531 if (PySys_Audit("os.scandir", "O",
13532 path->object ? path->object : Py_None) < 0) {
13533 return NULL;
13534 }
13535
Hai Shif707d942020-03-16 21:15:01 +080013536 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013537 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010013538 if (!iterator)
13539 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013540
13541#ifdef MS_WINDOWS
13542 iterator->handle = INVALID_HANDLE_VALUE;
13543#else
13544 iterator->dirp = NULL;
13545#endif
13546
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013547 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013548 /* Move the ownership to iterator->path */
13549 path->object = NULL;
13550 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013551
13552#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013553 iterator->first_time = 1;
13554
13555 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13556 if (!path_strW)
13557 goto error;
13558
13559 Py_BEGIN_ALLOW_THREADS
13560 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13561 Py_END_ALLOW_THREADS
13562
13563 PyMem_Free(path_strW);
13564
13565 if (iterator->handle == INVALID_HANDLE_VALUE) {
13566 path_error(&iterator->path);
13567 goto error;
13568 }
13569#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013570 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013571#ifdef HAVE_FDOPENDIR
13572 if (path->fd != -1) {
13573 /* closedir() closes the FD, so we duplicate it */
13574 fd = _Py_dup(path->fd);
13575 if (fd == -1)
13576 goto error;
13577
13578 Py_BEGIN_ALLOW_THREADS
13579 iterator->dirp = fdopendir(fd);
13580 Py_END_ALLOW_THREADS
13581 }
13582 else
13583#endif
13584 {
13585 if (iterator->path.narrow)
13586 path_str = iterator->path.narrow;
13587 else
13588 path_str = ".";
13589
13590 Py_BEGIN_ALLOW_THREADS
13591 iterator->dirp = opendir(path_str);
13592 Py_END_ALLOW_THREADS
13593 }
Victor Stinner6036e442015-03-08 01:58:04 +010013594
13595 if (!iterator->dirp) {
13596 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013597#ifdef HAVE_FDOPENDIR
13598 if (fd != -1) {
13599 Py_BEGIN_ALLOW_THREADS
13600 close(fd);
13601 Py_END_ALLOW_THREADS
13602 }
13603#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013604 goto error;
13605 }
13606#endif
13607
13608 return (PyObject *)iterator;
13609
13610error:
13611 Py_DECREF(iterator);
13612 return NULL;
13613}
13614
Ethan Furman410ef8e2016-06-04 12:06:26 -070013615/*
13616 Return the file system path representation of the object.
13617
13618 If the object is str or bytes, then allow it to pass through with
13619 an incremented refcount. If the object defines __fspath__(), then
13620 return the result of that method. All other types raise a TypeError.
13621*/
13622PyObject *
13623PyOS_FSPath(PyObject *path)
13624{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013625 /* For error message reasons, this function is manually inlined in
13626 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013627 PyObject *func = NULL;
13628 PyObject *path_repr = NULL;
13629
13630 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13631 Py_INCREF(path);
13632 return path;
13633 }
13634
13635 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13636 if (NULL == func) {
13637 return PyErr_Format(PyExc_TypeError,
13638 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013639 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080013640 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070013641 }
13642
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013643 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013644 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013645 if (NULL == path_repr) {
13646 return NULL;
13647 }
13648
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013649 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13650 PyErr_Format(PyExc_TypeError,
13651 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080013652 "not %.200s", _PyType_Name(Py_TYPE(path)),
13653 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013654 Py_DECREF(path_repr);
13655 return NULL;
13656 }
13657
Ethan Furman410ef8e2016-06-04 12:06:26 -070013658 return path_repr;
13659}
13660
13661/*[clinic input]
13662os.fspath
13663
13664 path: object
13665
13666Return the file system path representation of the object.
13667
Brett Cannonb4f43e92016-06-09 14:32:08 -070013668If the object is str or bytes, then allow it to pass through as-is. If the
13669object defines __fspath__(), then return the result of that method. All other
13670types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013671[clinic start generated code]*/
13672
13673static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013674os_fspath_impl(PyObject *module, PyObject *path)
13675/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013676{
13677 return PyOS_FSPath(path);
13678}
Victor Stinner6036e442015-03-08 01:58:04 +010013679
Victor Stinner9b1f4742016-09-06 16:18:52 -070013680#ifdef HAVE_GETRANDOM_SYSCALL
13681/*[clinic input]
13682os.getrandom
13683
13684 size: Py_ssize_t
13685 flags: int=0
13686
13687Obtain a series of random bytes.
13688[clinic start generated code]*/
13689
13690static PyObject *
13691os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13692/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13693{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013694 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013695 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013696
13697 if (size < 0) {
13698 errno = EINVAL;
13699 return posix_error();
13700 }
13701
Victor Stinnerec2319c2016-09-20 23:00:59 +020013702 bytes = PyBytes_FromStringAndSize(NULL, size);
13703 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013704 PyErr_NoMemory();
13705 return NULL;
13706 }
13707
13708 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013709 n = syscall(SYS_getrandom,
13710 PyBytes_AS_STRING(bytes),
13711 PyBytes_GET_SIZE(bytes),
13712 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013713 if (n < 0 && errno == EINTR) {
13714 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013715 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013716 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013717
13718 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013719 continue;
13720 }
13721 break;
13722 }
13723
13724 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013725 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013726 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013727 }
13728
Victor Stinnerec2319c2016-09-20 23:00:59 +020013729 if (n != size) {
13730 _PyBytes_Resize(&bytes, n);
13731 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013732
13733 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013734
13735error:
13736 Py_DECREF(bytes);
13737 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013738}
13739#endif /* HAVE_GETRANDOM_SYSCALL */
13740
Steve Dower2438cdf2019-03-29 16:37:16 -070013741#ifdef MS_WINDOWS
13742/* bpo-36085: Helper functions for managing DLL search directories
13743 * on win32
13744 */
13745
13746typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13747typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13748
13749/*[clinic input]
13750os._add_dll_directory
13751
13752 path: path_t
13753
13754Add a path to the DLL search path.
13755
13756This search path is used when resolving dependencies for imported
13757extension modules (the module itself is resolved through sys.path),
13758and also by ctypes.
13759
13760Returns an opaque value that may be passed to os.remove_dll_directory
13761to remove this directory from the search path.
13762[clinic start generated code]*/
13763
13764static PyObject *
13765os__add_dll_directory_impl(PyObject *module, path_t *path)
13766/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13767{
13768 HMODULE hKernel32;
13769 PAddDllDirectory AddDllDirectory;
13770 DLL_DIRECTORY_COOKIE cookie = 0;
13771 DWORD err = 0;
13772
Saiyang Gou7514f4f2020-02-12 23:47:42 -080013773 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
13774 return NULL;
13775 }
13776
Steve Dower2438cdf2019-03-29 16:37:16 -070013777 /* For Windows 7, we have to load this. As this will be a fairly
13778 infrequent operation, just do it each time. Kernel32 is always
13779 loaded. */
13780 Py_BEGIN_ALLOW_THREADS
13781 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13782 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13783 hKernel32, "AddDllDirectory")) ||
13784 !(cookie = (*AddDllDirectory)(path->wide))) {
13785 err = GetLastError();
13786 }
13787 Py_END_ALLOW_THREADS
13788
13789 if (err) {
13790 return win32_error_object_err("add_dll_directory",
13791 path->object, err);
13792 }
13793
13794 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13795}
13796
13797/*[clinic input]
13798os._remove_dll_directory
13799
13800 cookie: object
13801
13802Removes a path from the DLL search path.
13803
13804The parameter is an opaque value that was returned from
13805os.add_dll_directory. You can only remove directories that you added
13806yourself.
13807[clinic start generated code]*/
13808
13809static PyObject *
13810os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13811/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13812{
13813 HMODULE hKernel32;
13814 PRemoveDllDirectory RemoveDllDirectory;
13815 DLL_DIRECTORY_COOKIE cookieValue;
13816 DWORD err = 0;
13817
13818 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13819 PyErr_SetString(PyExc_TypeError,
13820 "Provided cookie was not returned from os.add_dll_directory");
13821 return NULL;
13822 }
13823
13824 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13825 cookie, "DLL directory cookie");
13826
13827 /* For Windows 7, we have to load this. As this will be a fairly
13828 infrequent operation, just do it each time. Kernel32 is always
13829 loaded. */
13830 Py_BEGIN_ALLOW_THREADS
13831 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13832 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13833 hKernel32, "RemoveDllDirectory")) ||
13834 !(*RemoveDllDirectory)(cookieValue)) {
13835 err = GetLastError();
13836 }
13837 Py_END_ALLOW_THREADS
13838
13839 if (err) {
13840 return win32_error_object_err("remove_dll_directory",
13841 NULL, err);
13842 }
13843
13844 if (PyCapsule_SetName(cookie, NULL)) {
13845 return NULL;
13846 }
13847
13848 Py_RETURN_NONE;
13849}
13850
13851#endif
Larry Hastings31826802013-10-19 00:09:25 -070013852
Victor Stinner65a796e2020-04-01 18:49:29 +020013853
13854/* Only check if WIFEXITED is available: expect that it comes
13855 with WEXITSTATUS, WIFSIGNALED, etc.
13856
13857 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
13858 subprocess can safely call it during late Python finalization without
13859 risking that used os attributes were set to None by _PyImport_Cleanup(). */
13860#if defined(WIFEXITED) || defined(MS_WINDOWS)
13861/*[clinic input]
13862os.waitstatus_to_exitcode
13863
Victor Stinner9bee32b2020-04-22 16:30:35 +020013864 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020013865
13866Convert a wait status to an exit code.
13867
13868On Unix:
13869
13870* If WIFEXITED(status) is true, return WEXITSTATUS(status).
13871* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
13872* Otherwise, raise a ValueError.
13873
13874On Windows, return status shifted right by 8 bits.
13875
13876On Unix, if the process is being traced or if waitpid() was called with
13877WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
13878This function must not be called if WIFSTOPPED(status) is true.
13879[clinic start generated code]*/
13880
13881static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020013882os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
13883/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020013884{
Victor Stinner9bee32b2020-04-22 16:30:35 +020013885 if (PyFloat_Check(status_obj)) {
13886 PyErr_SetString(PyExc_TypeError,
13887 "integer argument expected, got float" );
13888 return NULL;
13889 }
Victor Stinner65a796e2020-04-01 18:49:29 +020013890#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020013891 int status = _PyLong_AsInt(status_obj);
13892 if (status == -1 && PyErr_Occurred()) {
13893 return NULL;
13894 }
13895
Victor Stinner65a796e2020-04-01 18:49:29 +020013896 WAIT_TYPE wait_status;
13897 WAIT_STATUS_INT(wait_status) = status;
13898 int exitcode;
13899 if (WIFEXITED(wait_status)) {
13900 exitcode = WEXITSTATUS(wait_status);
13901 /* Sanity check to provide warranty on the function behavior.
13902 It should not occur in practice */
13903 if (exitcode < 0) {
13904 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
13905 return NULL;
13906 }
13907 }
13908 else if (WIFSIGNALED(wait_status)) {
13909 int signum = WTERMSIG(wait_status);
13910 /* Sanity check to provide warranty on the function behavior.
13911 It should not occurs in practice */
13912 if (signum <= 0) {
13913 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
13914 return NULL;
13915 }
13916 exitcode = -signum;
13917 } else if (WIFSTOPPED(wait_status)) {
13918 /* Status only received if the process is being traced
13919 or if waitpid() was called with WUNTRACED option. */
13920 int signum = WSTOPSIG(wait_status);
13921 PyErr_Format(PyExc_ValueError,
13922 "process stopped by delivery of signal %i",
13923 signum);
13924 return NULL;
13925 }
13926 else {
13927 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
13928 return NULL;
13929 }
13930 return PyLong_FromLong(exitcode);
13931#else
13932 /* Windows implementation: see os.waitpid() implementation
13933 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020013934 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
13935 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
13936 return NULL;
13937 }
13938
13939 unsigned long long exitcode = (status >> 8);
13940 /* ExitProcess() accepts an UINT type:
13941 reject exit code which doesn't fit in an UINT */
13942 if (exitcode > UINT_MAX) {
13943 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
13944 return NULL;
13945 }
13946 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020013947#endif
13948}
13949#endif
13950
13951
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013952static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013953
13954 OS_STAT_METHODDEF
13955 OS_ACCESS_METHODDEF
13956 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013957 OS_CHDIR_METHODDEF
13958 OS_CHFLAGS_METHODDEF
13959 OS_CHMOD_METHODDEF
13960 OS_FCHMOD_METHODDEF
13961 OS_LCHMOD_METHODDEF
13962 OS_CHOWN_METHODDEF
13963 OS_FCHOWN_METHODDEF
13964 OS_LCHOWN_METHODDEF
13965 OS_LCHFLAGS_METHODDEF
13966 OS_CHROOT_METHODDEF
13967 OS_CTERMID_METHODDEF
13968 OS_GETCWD_METHODDEF
13969 OS_GETCWDB_METHODDEF
13970 OS_LINK_METHODDEF
13971 OS_LISTDIR_METHODDEF
13972 OS_LSTAT_METHODDEF
13973 OS_MKDIR_METHODDEF
13974 OS_NICE_METHODDEF
13975 OS_GETPRIORITY_METHODDEF
13976 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000013977 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030013978 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013979 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010013980 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013981 OS_RENAME_METHODDEF
13982 OS_REPLACE_METHODDEF
13983 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013984 OS_SYMLINK_METHODDEF
13985 OS_SYSTEM_METHODDEF
13986 OS_UMASK_METHODDEF
13987 OS_UNAME_METHODDEF
13988 OS_UNLINK_METHODDEF
13989 OS_REMOVE_METHODDEF
13990 OS_UTIME_METHODDEF
13991 OS_TIMES_METHODDEF
13992 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020013993 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013994 OS_EXECV_METHODDEF
13995 OS_EXECVE_METHODDEF
13996 OS_SPAWNV_METHODDEF
13997 OS_SPAWNVE_METHODDEF
13998 OS_FORK1_METHODDEF
13999 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014000 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014001 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14002 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14003 OS_SCHED_GETPARAM_METHODDEF
14004 OS_SCHED_GETSCHEDULER_METHODDEF
14005 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14006 OS_SCHED_SETPARAM_METHODDEF
14007 OS_SCHED_SETSCHEDULER_METHODDEF
14008 OS_SCHED_YIELD_METHODDEF
14009 OS_SCHED_SETAFFINITY_METHODDEF
14010 OS_SCHED_GETAFFINITY_METHODDEF
14011 OS_OPENPTY_METHODDEF
14012 OS_FORKPTY_METHODDEF
14013 OS_GETEGID_METHODDEF
14014 OS_GETEUID_METHODDEF
14015 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014016 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014017 OS_GETGROUPS_METHODDEF
14018 OS_GETPID_METHODDEF
14019 OS_GETPGRP_METHODDEF
14020 OS_GETPPID_METHODDEF
14021 OS_GETUID_METHODDEF
14022 OS_GETLOGIN_METHODDEF
14023 OS_KILL_METHODDEF
14024 OS_KILLPG_METHODDEF
14025 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014026 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014027 OS_SETUID_METHODDEF
14028 OS_SETEUID_METHODDEF
14029 OS_SETREUID_METHODDEF
14030 OS_SETGID_METHODDEF
14031 OS_SETEGID_METHODDEF
14032 OS_SETREGID_METHODDEF
14033 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014034 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014035 OS_GETPGID_METHODDEF
14036 OS_SETPGRP_METHODDEF
14037 OS_WAIT_METHODDEF
14038 OS_WAIT3_METHODDEF
14039 OS_WAIT4_METHODDEF
14040 OS_WAITID_METHODDEF
14041 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014042 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014043 OS_GETSID_METHODDEF
14044 OS_SETSID_METHODDEF
14045 OS_SETPGID_METHODDEF
14046 OS_TCGETPGRP_METHODDEF
14047 OS_TCSETPGRP_METHODDEF
14048 OS_OPEN_METHODDEF
14049 OS_CLOSE_METHODDEF
14050 OS_CLOSERANGE_METHODDEF
14051 OS_DEVICE_ENCODING_METHODDEF
14052 OS_DUP_METHODDEF
14053 OS_DUP2_METHODDEF
14054 OS_LOCKF_METHODDEF
14055 OS_LSEEK_METHODDEF
14056 OS_READ_METHODDEF
14057 OS_READV_METHODDEF
14058 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014059 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014060 OS_WRITE_METHODDEF
14061 OS_WRITEV_METHODDEF
14062 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014063 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014064 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014065 OS_FSTAT_METHODDEF
14066 OS_ISATTY_METHODDEF
14067 OS_PIPE_METHODDEF
14068 OS_PIPE2_METHODDEF
14069 OS_MKFIFO_METHODDEF
14070 OS_MKNOD_METHODDEF
14071 OS_MAJOR_METHODDEF
14072 OS_MINOR_METHODDEF
14073 OS_MAKEDEV_METHODDEF
14074 OS_FTRUNCATE_METHODDEF
14075 OS_TRUNCATE_METHODDEF
14076 OS_POSIX_FALLOCATE_METHODDEF
14077 OS_POSIX_FADVISE_METHODDEF
14078 OS_PUTENV_METHODDEF
14079 OS_UNSETENV_METHODDEF
14080 OS_STRERROR_METHODDEF
14081 OS_FCHDIR_METHODDEF
14082 OS_FSYNC_METHODDEF
14083 OS_SYNC_METHODDEF
14084 OS_FDATASYNC_METHODDEF
14085 OS_WCOREDUMP_METHODDEF
14086 OS_WIFCONTINUED_METHODDEF
14087 OS_WIFSTOPPED_METHODDEF
14088 OS_WIFSIGNALED_METHODDEF
14089 OS_WIFEXITED_METHODDEF
14090 OS_WEXITSTATUS_METHODDEF
14091 OS_WTERMSIG_METHODDEF
14092 OS_WSTOPSIG_METHODDEF
14093 OS_FSTATVFS_METHODDEF
14094 OS_STATVFS_METHODDEF
14095 OS_CONFSTR_METHODDEF
14096 OS_SYSCONF_METHODDEF
14097 OS_FPATHCONF_METHODDEF
14098 OS_PATHCONF_METHODDEF
14099 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014100 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014101 OS__GETDISKUSAGE_METHODDEF
14102 OS__GETFINALPATHNAME_METHODDEF
14103 OS__GETVOLUMEPATHNAME_METHODDEF
14104 OS_GETLOADAVG_METHODDEF
14105 OS_URANDOM_METHODDEF
14106 OS_SETRESUID_METHODDEF
14107 OS_SETRESGID_METHODDEF
14108 OS_GETRESUID_METHODDEF
14109 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014110
Larry Hastings2f936352014-08-05 14:04:04 +100014111 OS_GETXATTR_METHODDEF
14112 OS_SETXATTR_METHODDEF
14113 OS_REMOVEXATTR_METHODDEF
14114 OS_LISTXATTR_METHODDEF
14115
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014116 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014117 OS_CPU_COUNT_METHODDEF
14118 OS_GET_INHERITABLE_METHODDEF
14119 OS_SET_INHERITABLE_METHODDEF
14120 OS_GET_HANDLE_INHERITABLE_METHODDEF
14121 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014122 OS_GET_BLOCKING_METHODDEF
14123 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014124 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014125 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014126 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014127 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014128 OS__ADD_DLL_DIRECTORY_METHODDEF
14129 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014130 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014131 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014132};
14133
Barry Warsaw4a342091996-12-19 23:50:02 +000014134static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014135all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014136{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014137#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014138 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014139#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014140#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014141 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014142#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014143#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014144 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014145#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014146#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014147 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014148#endif
Fred Drakec9680921999-12-13 16:37:25 +000014149#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014150 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014151#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014152#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014153 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014154#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014155#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014156 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014157#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014158#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014159 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014160#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014161#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014162 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014163#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014164#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014165 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014166#endif
14167#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014168 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014169#endif
14170#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014171 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014172#endif
14173#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014174 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014175#endif
14176#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014177 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014178#endif
14179#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014180 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014181#endif
14182#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014183 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014184#endif
14185#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014186 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014187#endif
14188#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014189 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014190#endif
14191#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014192 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014193#endif
14194#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014195 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014196#endif
14197#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014198 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014199#endif
14200#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014201 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014202#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014203#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014204 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014205#endif
14206#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014207 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014208#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014209#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014210 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014211#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014212#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014213 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014214#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014215#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014216#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014217 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014218#endif
14219#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014220 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014221#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014222#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014223#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014224 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014225#endif
14226#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014227 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014228#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014229#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014230 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014231#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014232#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014233 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014234#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014235#ifdef O_TMPFILE
14236 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14237#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014238#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014239 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014240#endif
14241#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014242 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014243#endif
14244#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014245 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014246#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014247#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014248 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014249#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014250#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014251 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014252#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014253
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014254
Jesus Cea94363612012-06-22 18:32:07 +020014255#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014256 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014257#endif
14258#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014259 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014260#endif
14261
Tim Peters5aa91602002-01-30 05:46:57 +000014262/* MS Windows */
14263#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014264 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014265 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014266#endif
14267#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000014268 /* Optimize for short life (keep in memory). */
14269 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014270 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014271#endif
14272#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000014273 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014274 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014275#endif
14276#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000014277 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014278 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014279#endif
14280#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014281 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014282 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014283#endif
14284
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014285/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014286#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014287 /* Send a SIGIO signal whenever input or output
14288 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014289 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014290#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014291#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014292 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014293 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014294#endif
14295#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000014296 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014297 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014298#endif
14299#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000014300 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014301 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014302#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014303#ifdef O_NOLINKS
14304 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014305 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014306#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014307#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014308 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014309 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014310#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000014311
Victor Stinner8c62be82010-05-06 00:08:46 +000014312 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014313#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014314 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014315#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014316#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014317 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014318#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014319#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014320 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014321#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014322#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014323 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014324#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014325#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014326 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014327#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014328#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014329 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014330#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014331#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014332 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014333#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014334#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014335 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014336#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014337#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014338 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014339#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014340#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014341 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014342#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014343#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014344 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014345#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014346#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014347 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014348#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014349#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014350 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014351#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014352#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014353 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014354#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014355#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014356 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014357#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014358#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014359 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014360#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014361#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014362 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014363#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014364
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000014365 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014366#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014367 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014368#endif /* ST_RDONLY */
14369#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014370 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014371#endif /* ST_NOSUID */
14372
doko@ubuntu.comca616a22013-12-08 15:23:07 +010014373 /* GNU extensions */
14374#ifdef ST_NODEV
14375 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
14376#endif /* ST_NODEV */
14377#ifdef ST_NOEXEC
14378 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
14379#endif /* ST_NOEXEC */
14380#ifdef ST_SYNCHRONOUS
14381 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
14382#endif /* ST_SYNCHRONOUS */
14383#ifdef ST_MANDLOCK
14384 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
14385#endif /* ST_MANDLOCK */
14386#ifdef ST_WRITE
14387 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
14388#endif /* ST_WRITE */
14389#ifdef ST_APPEND
14390 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
14391#endif /* ST_APPEND */
14392#ifdef ST_NOATIME
14393 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
14394#endif /* ST_NOATIME */
14395#ifdef ST_NODIRATIME
14396 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
14397#endif /* ST_NODIRATIME */
14398#ifdef ST_RELATIME
14399 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
14400#endif /* ST_RELATIME */
14401
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014402 /* FreeBSD sendfile() constants */
14403#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014404 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014405#endif
14406#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014407 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014408#endif
14409#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014410 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014411#endif
14412
Ross Lagerwall7807c352011-03-17 20:20:30 +020014413 /* constants for posix_fadvise */
14414#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014415 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014416#endif
14417#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014418 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014419#endif
14420#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014421 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014422#endif
14423#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014424 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014425#endif
14426#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014427 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014428#endif
14429#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014430 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014431#endif
14432
14433 /* constants for waitid */
14434#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014435 if (PyModule_AddIntMacro(m, P_PID)) return -1;
14436 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
14437 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080014438#ifdef P_PIDFD
14439 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
14440#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014441#endif
14442#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014443 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014444#endif
14445#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014446 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014447#endif
14448#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014449 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014450#endif
14451#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014452 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014453#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014454#ifdef CLD_KILLED
14455 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
14456#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014457#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014458 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014459#endif
14460#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014461 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014462#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014463#ifdef CLD_STOPPED
14464 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
14465#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014466#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014467 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014468#endif
14469
14470 /* constants for lockf */
14471#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014472 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014473#endif
14474#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014475 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014476#endif
14477#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014478 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014479#endif
14480#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014481 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014482#endif
14483
Pablo Galindo4defba32018-01-27 16:16:37 +000014484#ifdef RWF_DSYNC
14485 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14486#endif
14487#ifdef RWF_HIPRI
14488 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14489#endif
14490#ifdef RWF_SYNC
14491 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14492#endif
14493#ifdef RWF_NOWAIT
14494 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14495#endif
14496
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014497/* constants for posix_spawn */
14498#ifdef HAVE_POSIX_SPAWN
14499 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14500 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14501 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14502#endif
14503
pxinwrf2d7ac72019-05-21 18:46:37 +080014504#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014505 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14506 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014507 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014508#endif
14509#ifdef HAVE_SPAWNV
14510 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014511 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014512#endif
14513
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014514#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014515#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014516 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014517#endif
14518#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014519 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014520#endif
14521#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014522 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014523#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014524#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014525 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014526#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014527#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014528 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014529#endif
14530#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014531 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014532#endif
14533#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014534 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014535#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014536#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014537 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014538#endif
14539#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014540 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014541#endif
14542#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014543 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014544#endif
14545#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014546 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014547#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014548#endif
14549
Benjamin Peterson9428d532011-09-14 11:45:52 -040014550#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014551 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14552 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14553 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014554#endif
14555
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014556#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014557 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014558#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014559#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014560 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014561#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014562#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014563 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014564#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014565#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014566 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014567#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014568#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014569 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014570#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014571#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014572 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014573#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014574#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014575 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014576#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014577#if HAVE_DECL_RTLD_MEMBER
14578 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14579#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014580
Victor Stinner9b1f4742016-09-06 16:18:52 -070014581#ifdef HAVE_GETRANDOM_SYSCALL
14582 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14583 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14584#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014585#ifdef HAVE_MEMFD_CREATE
14586 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14587 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14588#ifdef MFD_HUGETLB
14589 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014590#endif
14591#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014592 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014593#endif
14594#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014595 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014596#endif
14597#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014598 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014599#endif
14600#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014601 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014602#endif
14603#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014604 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014605#endif
14606#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014607 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014608#endif
14609#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014610 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014611#endif
14612#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014613 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014614#endif
14615#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014616 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014617#endif
14618#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014619 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014620#endif
14621#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014622 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014623#endif
14624#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014625 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014626#endif
14627#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014628 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014629#endif
14630#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014631 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14632#endif
14633#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014634
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014635#if defined(__APPLE__)
14636 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14637#endif
14638
Steve Dower2438cdf2019-03-29 16:37:16 -070014639#ifdef MS_WINDOWS
14640 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14641 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14642 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14643 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14644 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14645#endif
14646
Victor Stinner8c62be82010-05-06 00:08:46 +000014647 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014648}
14649
14650
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014651static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014652
14653#ifdef HAVE_FACCESSAT
14654 "HAVE_FACCESSAT",
14655#endif
14656
14657#ifdef HAVE_FCHDIR
14658 "HAVE_FCHDIR",
14659#endif
14660
14661#ifdef HAVE_FCHMOD
14662 "HAVE_FCHMOD",
14663#endif
14664
14665#ifdef HAVE_FCHMODAT
14666 "HAVE_FCHMODAT",
14667#endif
14668
14669#ifdef HAVE_FCHOWN
14670 "HAVE_FCHOWN",
14671#endif
14672
Larry Hastings00964ed2013-08-12 13:49:30 -040014673#ifdef HAVE_FCHOWNAT
14674 "HAVE_FCHOWNAT",
14675#endif
14676
Larry Hastings9cf065c2012-06-22 16:30:09 -070014677#ifdef HAVE_FEXECVE
14678 "HAVE_FEXECVE",
14679#endif
14680
14681#ifdef HAVE_FDOPENDIR
14682 "HAVE_FDOPENDIR",
14683#endif
14684
Georg Brandl306336b2012-06-24 12:55:33 +020014685#ifdef HAVE_FPATHCONF
14686 "HAVE_FPATHCONF",
14687#endif
14688
Larry Hastings9cf065c2012-06-22 16:30:09 -070014689#ifdef HAVE_FSTATAT
14690 "HAVE_FSTATAT",
14691#endif
14692
14693#ifdef HAVE_FSTATVFS
14694 "HAVE_FSTATVFS",
14695#endif
14696
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014697#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014698 "HAVE_FTRUNCATE",
14699#endif
14700
Larry Hastings9cf065c2012-06-22 16:30:09 -070014701#ifdef HAVE_FUTIMENS
14702 "HAVE_FUTIMENS",
14703#endif
14704
14705#ifdef HAVE_FUTIMES
14706 "HAVE_FUTIMES",
14707#endif
14708
14709#ifdef HAVE_FUTIMESAT
14710 "HAVE_FUTIMESAT",
14711#endif
14712
14713#ifdef HAVE_LINKAT
14714 "HAVE_LINKAT",
14715#endif
14716
14717#ifdef HAVE_LCHFLAGS
14718 "HAVE_LCHFLAGS",
14719#endif
14720
14721#ifdef HAVE_LCHMOD
14722 "HAVE_LCHMOD",
14723#endif
14724
14725#ifdef HAVE_LCHOWN
14726 "HAVE_LCHOWN",
14727#endif
14728
14729#ifdef HAVE_LSTAT
14730 "HAVE_LSTAT",
14731#endif
14732
14733#ifdef HAVE_LUTIMES
14734 "HAVE_LUTIMES",
14735#endif
14736
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014737#ifdef HAVE_MEMFD_CREATE
14738 "HAVE_MEMFD_CREATE",
14739#endif
14740
Larry Hastings9cf065c2012-06-22 16:30:09 -070014741#ifdef HAVE_MKDIRAT
14742 "HAVE_MKDIRAT",
14743#endif
14744
14745#ifdef HAVE_MKFIFOAT
14746 "HAVE_MKFIFOAT",
14747#endif
14748
14749#ifdef HAVE_MKNODAT
14750 "HAVE_MKNODAT",
14751#endif
14752
14753#ifdef HAVE_OPENAT
14754 "HAVE_OPENAT",
14755#endif
14756
14757#ifdef HAVE_READLINKAT
14758 "HAVE_READLINKAT",
14759#endif
14760
14761#ifdef HAVE_RENAMEAT
14762 "HAVE_RENAMEAT",
14763#endif
14764
14765#ifdef HAVE_SYMLINKAT
14766 "HAVE_SYMLINKAT",
14767#endif
14768
14769#ifdef HAVE_UNLINKAT
14770 "HAVE_UNLINKAT",
14771#endif
14772
14773#ifdef HAVE_UTIMENSAT
14774 "HAVE_UTIMENSAT",
14775#endif
14776
14777#ifdef MS_WINDOWS
14778 "MS_WINDOWS",
14779#endif
14780
14781 NULL
14782};
14783
14784
Victor Stinner1c2fa782020-05-10 11:05:29 +020014785static int
14786posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014787{
Victor Stinner1c2fa782020-05-10 11:05:29 +020014788 PyObject *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014789 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014790 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000014791
Victor Stinner8c62be82010-05-06 00:08:46 +000014792 /* Initialize environ dictionary */
14793 v = convertenviron();
14794 Py_XINCREF(v);
14795 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014796 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014797 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014798
Victor Stinner8c62be82010-05-06 00:08:46 +000014799 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014800 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014801
Victor Stinner8c62be82010-05-06 00:08:46 +000014802 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014803 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000014804
Victor Stinner8c62be82010-05-06 00:08:46 +000014805 Py_INCREF(PyExc_OSError);
14806 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014807
Ross Lagerwall7807c352011-03-17 20:20:30 +020014808#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080014809 waitid_result_desc.name = MODNAME ".waitid_result";
14810 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
14811 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014812 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014813 }
14814 Py_INCREF(WaitidResultType);
14815 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Hai Shif707d942020-03-16 21:15:01 +080014816 get_posix_state(m)->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014817#endif
14818
Eddie Elizondob3966632019-11-05 07:16:14 -080014819 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
14820 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14821 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14822 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
14823 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
14824 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014825 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014826 }
14827 Py_INCREF(StatResultType);
14828 PyModule_AddObject(m, "stat_result", StatResultType);
Hai Shif707d942020-03-16 21:15:01 +080014829 get_posix_state(m)->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014830 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
14831 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014832
Eddie Elizondob3966632019-11-05 07:16:14 -080014833 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
14834 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
14835 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014836 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014837 }
14838 Py_INCREF(StatVFSResultType);
14839 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Hai Shif707d942020-03-16 21:15:01 +080014840 get_posix_state(m)->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014841#ifdef NEED_TICKS_PER_SECOND
14842# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080014843 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014844# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080014845 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014846# else
Eddie Elizondob3966632019-11-05 07:16:14 -080014847 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014848# endif
14849#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014850
William Orr81574b82018-10-01 22:19:56 -070014851#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080014852 sched_param_desc.name = MODNAME ".sched_param";
14853 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
14854 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014855 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014856 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014857 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080014858 PyModule_AddObject(m, "sched_param", SchedParamType);
Hai Shif707d942020-03-16 21:15:01 +080014859 get_posix_state(m)->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014860 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014861#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014862
Eddie Elizondob3966632019-11-05 07:16:14 -080014863 /* initialize TerminalSize_info */
14864 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
14865 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014866 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014867 }
14868 Py_INCREF(TerminalSizeType);
14869 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Hai Shif707d942020-03-16 21:15:01 +080014870 get_posix_state(m)->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014871
14872 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020014873 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080014874 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014875 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014876 }
Hai Shif707d942020-03-16 21:15:01 +080014877 get_posix_state(m)->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014878
Victor Stinner1c2fa782020-05-10 11:05:29 +020014879 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080014880 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014881 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014882 }
14883 Py_INCREF(DirEntryType);
14884 PyModule_AddObject(m, "DirEntry", DirEntryType);
Hai Shif707d942020-03-16 21:15:01 +080014885 get_posix_state(m)->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014886
Larry Hastings605a62d2012-06-24 04:33:36 -070014887 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080014888 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014889 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014890 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014891 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014892 Py_INCREF(TimesResultType);
14893 PyModule_AddObject(m, "times_result", TimesResultType);
Hai Shif707d942020-03-16 21:15:01 +080014894 get_posix_state(m)->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014895
Eddie Elizondob3966632019-11-05 07:16:14 -080014896 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014897 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014898 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014899 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014900 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014901 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Hai Shif707d942020-03-16 21:15:01 +080014902 get_posix_state(m)->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014903
Thomas Wouters477c8d52006-05-27 19:21:47 +000014904#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014905 /*
14906 * Step 2 of weak-linking support on Mac OS X.
14907 *
14908 * The code below removes functions that are not available on the
14909 * currently active platform.
14910 *
14911 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014912 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014913 * OSX 10.4.
14914 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014915#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014916 if (fstatvfs == NULL) {
14917 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014918 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014919 }
14920 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014921#endif /* HAVE_FSTATVFS */
14922
14923#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014924 if (statvfs == NULL) {
14925 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014926 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014927 }
14928 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014929#endif /* HAVE_STATVFS */
14930
14931# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014932 if (lchown == NULL) {
14933 if (PyObject_DelAttrString(m, "lchown") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014934 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014935 }
14936 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014937#endif /* HAVE_LCHOWN */
14938
14939
14940#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014941
Hai Shif707d942020-03-16 21:15:01 +080014942 if ((get_posix_state(m)->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014943 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014944#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Hai Shif707d942020-03-16 21:15:01 +080014945 get_posix_state(m)->struct_rusage = PyUnicode_InternFromString("struct_rusage");
14946 if (get_posix_state(m)->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014947 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014948#endif
Hai Shif707d942020-03-16 21:15:01 +080014949 get_posix_state(m)->st_mode = PyUnicode_InternFromString("st_mode");
14950 if (get_posix_state(m)->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014951 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070014952
Larry Hastings9cf065c2012-06-22 16:30:09 -070014953 /* suppress "function not used" warnings */
14954 {
14955 int ignored;
14956 fd_specified("", -1);
14957 follow_symlinks_specified("", 1);
14958 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14959 dir_fd_converter(Py_None, &ignored);
14960 dir_fd_unavailable(Py_None, &ignored);
14961 }
14962
14963 /*
14964 * provide list of locally available functions
14965 * so os.py can populate support_* lists
14966 */
14967 list = PyList_New(0);
14968 if (!list)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014969 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014970 for (trace = have_functions; *trace; trace++) {
14971 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
14972 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014973 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014974 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014975 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070014976 Py_DECREF(unicode);
14977 }
14978 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040014979
Victor Stinner1c2fa782020-05-10 11:05:29 +020014980 return 0;
14981}
14982
14983
14984static PyModuleDef_Slot posixmodile_slots[] = {
14985 {Py_mod_exec, posixmodule_exec},
14986 {0, NULL}
14987};
14988
14989static struct PyModuleDef posixmodule = {
14990 PyModuleDef_HEAD_INIT,
14991 .m_name = MODNAME,
14992 .m_doc = posix__doc__,
14993 .m_size = sizeof(_posixstate),
14994 .m_methods = posix_methods,
14995 .m_slots = posixmodile_slots,
14996 .m_traverse = _posix_traverse,
14997 .m_clear = _posix_clear,
14998 .m_free = _posix_free,
14999};
15000
15001PyMODINIT_FUNC
15002INITFUNC(void)
15003{
15004 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015005}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015006
15007#ifdef __cplusplus
15008}
15009#endif