blob: 39f5f577a8286f44d52885a9c94599630b0f4903 [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{
Victor Stinner97f33c32020-05-14 18:05:58 +02002104 _posixstate *state = get_posix_state(module);
2105 Py_CLEAR(state->billion);
2106 Py_CLEAR(state->DirEntryType);
2107 Py_CLEAR(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002108#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002109 Py_CLEAR(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002110#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002111 Py_CLEAR(state->StatResultType);
2112 Py_CLEAR(state->StatVFSResultType);
2113 Py_CLEAR(state->TerminalSizeType);
2114 Py_CLEAR(state->TimesResultType);
2115 Py_CLEAR(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002116#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002117 Py_CLEAR(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002118#endif
2119#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002120 Py_CLEAR(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002121#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002122 Py_CLEAR(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002123 return 0;
2124}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002125
Eddie Elizondob3966632019-11-05 07:16:14 -08002126static int
2127_posix_traverse(PyObject *module, visitproc visit, void *arg)
2128{
Victor Stinner97f33c32020-05-14 18:05:58 +02002129 _posixstate *state = get_posix_state(module);
2130 Py_VISIT(state->billion);
2131 Py_VISIT(state->DirEntryType);
2132 Py_VISIT(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002133#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002134 Py_VISIT(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002135#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002136 Py_VISIT(state->StatResultType);
2137 Py_VISIT(state->StatVFSResultType);
2138 Py_VISIT(state->TerminalSizeType);
2139 Py_VISIT(state->TimesResultType);
2140 Py_VISIT(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002141#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002142 Py_VISIT(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002143#endif
2144#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002145 Py_VISIT(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002146#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002147 Py_VISIT(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002148 return 0;
2149}
2150
2151static void
2152_posix_free(void *module)
2153{
2154 _posix_clear((PyObject *)module);
2155}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002156
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002157static void
Victor Stinner1c2fa782020-05-10 11:05:29 +02002158fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002159{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002160 PyObject *s = _PyLong_FromTime_t(sec);
2161 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2162 PyObject *s_in_ns = NULL;
2163 PyObject *ns_total = NULL;
2164 PyObject *float_s = NULL;
2165
2166 if (!(s && ns_fractional))
2167 goto exit;
2168
Victor Stinner1c2fa782020-05-10 11:05:29 +02002169 s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002170 if (!s_in_ns)
2171 goto exit;
2172
2173 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2174 if (!ns_total)
2175 goto exit;
2176
Victor Stinner01b5aab2017-10-24 02:02:00 -07002177 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2178 if (!float_s) {
2179 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002180 }
2181
2182 PyStructSequence_SET_ITEM(v, index, s);
2183 PyStructSequence_SET_ITEM(v, index+3, float_s);
2184 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2185 s = NULL;
2186 float_s = NULL;
2187 ns_total = NULL;
2188exit:
2189 Py_XDECREF(s);
2190 Py_XDECREF(ns_fractional);
2191 Py_XDECREF(s_in_ns);
2192 Py_XDECREF(ns_total);
2193 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002194}
2195
Tim Peters5aa91602002-01-30 05:46:57 +00002196/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002197 (used by posix_stat() and posix_fstat()) */
2198static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +02002199_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002200{
Victor Stinner8c62be82010-05-06 00:08:46 +00002201 unsigned long ansec, mnsec, cnsec;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002202 PyObject *StatResultType = get_posix_state(module)->StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08002203 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002204 if (v == NULL)
2205 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002206
Victor Stinner8c62be82010-05-06 00:08:46 +00002207 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002208 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002209 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002210#ifdef MS_WINDOWS
2211 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002212#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002213 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002214#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002215 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002216#if defined(MS_WINDOWS)
2217 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2218 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2219#else
2220 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2221 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2222#endif
xdegaye50e86032017-05-22 11:15:08 +02002223 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2224 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002225
Martin v. Löwis14694662006-02-03 12:54:16 +00002226#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002227 ansec = st->st_atim.tv_nsec;
2228 mnsec = st->st_mtim.tv_nsec;
2229 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002230#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002231 ansec = st->st_atimespec.tv_nsec;
2232 mnsec = st->st_mtimespec.tv_nsec;
2233 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002234#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002235 ansec = st->st_atime_nsec;
2236 mnsec = st->st_mtime_nsec;
2237 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002238#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002239 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002240#endif
Victor Stinner1c2fa782020-05-10 11:05:29 +02002241 fill_time(module, v, 7, st->st_atime, ansec);
2242 fill_time(module, v, 8, st->st_mtime, mnsec);
2243 fill_time(module, v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002244
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002245#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002246 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2247 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002248#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002249#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002250 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2251 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002252#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002253#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002254 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2255 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002256#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002257#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002258 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2259 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002260#endif
2261#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002262 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002263 PyObject *val;
2264 unsigned long bsec,bnsec;
2265 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002266#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002267 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002268#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002269 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002270#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002271 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002272 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2273 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002274 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002275#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002276#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002277 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2278 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002279#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002280#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2281 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2282 PyLong_FromUnsignedLong(st->st_file_attributes));
2283#endif
jcea6c51d512018-01-28 14:00:08 +01002284#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2285 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2286 PyUnicode_FromString(st->st_fstype));
2287#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002288#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2289 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2290 PyLong_FromUnsignedLong(st->st_reparse_tag));
2291#endif
Fred Drake699f3522000-06-29 21:12:41 +00002292
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 if (PyErr_Occurred()) {
2294 Py_DECREF(v);
2295 return NULL;
2296 }
Fred Drake699f3522000-06-29 21:12:41 +00002297
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002299}
2300
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002301/* POSIX methods */
2302
Guido van Rossum94f6f721999-01-06 18:42:14 +00002303
2304static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02002305posix_do_stat(PyObject *module, const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002306 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002307{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002308 STRUCT_STAT st;
2309 int result;
2310
2311#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2312 if (follow_symlinks_specified(function_name, follow_symlinks))
2313 return NULL;
2314#endif
2315
2316 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2317 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2318 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2319 return NULL;
2320
2321 Py_BEGIN_ALLOW_THREADS
2322 if (path->fd != -1)
2323 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002324#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002325 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002326 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002327 else
Steve Dowercc16be82016-09-08 10:35:16 -07002328 result = win32_lstat(path->wide, &st);
2329#else
2330 else
2331#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002332 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2333 result = LSTAT(path->narrow, &st);
2334 else
Steve Dowercc16be82016-09-08 10:35:16 -07002335#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002336#ifdef HAVE_FSTATAT
2337 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2338 result = fstatat(dir_fd, path->narrow, &st,
2339 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2340 else
Steve Dowercc16be82016-09-08 10:35:16 -07002341#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002342 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002343#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002344 Py_END_ALLOW_THREADS
2345
Victor Stinner292c8352012-10-30 02:17:38 +01002346 if (result != 0) {
2347 return path_error(path);
2348 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002349
Victor Stinner1c2fa782020-05-10 11:05:29 +02002350 return _pystat_fromstructstat(module, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002351}
2352
Larry Hastings2f936352014-08-05 14:04:04 +10002353/*[python input]
2354
2355for s in """
2356
2357FACCESSAT
2358FCHMODAT
2359FCHOWNAT
2360FSTATAT
2361LINKAT
2362MKDIRAT
2363MKFIFOAT
2364MKNODAT
2365OPENAT
2366READLINKAT
2367SYMLINKAT
2368UNLINKAT
2369
2370""".strip().split():
2371 s = s.strip()
2372 print("""
2373#ifdef HAVE_{s}
2374 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002375#else
Larry Hastings2f936352014-08-05 14:04:04 +10002376 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002377#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002378""".rstrip().format(s=s))
2379
2380for s in """
2381
2382FCHDIR
2383FCHMOD
2384FCHOWN
2385FDOPENDIR
2386FEXECVE
2387FPATHCONF
2388FSTATVFS
2389FTRUNCATE
2390
2391""".strip().split():
2392 s = s.strip()
2393 print("""
2394#ifdef HAVE_{s}
2395 #define PATH_HAVE_{s} 1
2396#else
2397 #define PATH_HAVE_{s} 0
2398#endif
2399
2400""".rstrip().format(s=s))
2401[python start generated code]*/
2402
2403#ifdef HAVE_FACCESSAT
2404 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2405#else
2406 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2407#endif
2408
2409#ifdef HAVE_FCHMODAT
2410 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2411#else
2412 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2413#endif
2414
2415#ifdef HAVE_FCHOWNAT
2416 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2417#else
2418 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2419#endif
2420
2421#ifdef HAVE_FSTATAT
2422 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2423#else
2424 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2425#endif
2426
2427#ifdef HAVE_LINKAT
2428 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2429#else
2430 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2431#endif
2432
2433#ifdef HAVE_MKDIRAT
2434 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2435#else
2436 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2437#endif
2438
2439#ifdef HAVE_MKFIFOAT
2440 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2441#else
2442 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2443#endif
2444
2445#ifdef HAVE_MKNODAT
2446 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2447#else
2448 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2449#endif
2450
2451#ifdef HAVE_OPENAT
2452 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2453#else
2454 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2455#endif
2456
2457#ifdef HAVE_READLINKAT
2458 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2459#else
2460 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2461#endif
2462
2463#ifdef HAVE_SYMLINKAT
2464 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2465#else
2466 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2467#endif
2468
2469#ifdef HAVE_UNLINKAT
2470 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2471#else
2472 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2473#endif
2474
2475#ifdef HAVE_FCHDIR
2476 #define PATH_HAVE_FCHDIR 1
2477#else
2478 #define PATH_HAVE_FCHDIR 0
2479#endif
2480
2481#ifdef HAVE_FCHMOD
2482 #define PATH_HAVE_FCHMOD 1
2483#else
2484 #define PATH_HAVE_FCHMOD 0
2485#endif
2486
2487#ifdef HAVE_FCHOWN
2488 #define PATH_HAVE_FCHOWN 1
2489#else
2490 #define PATH_HAVE_FCHOWN 0
2491#endif
2492
2493#ifdef HAVE_FDOPENDIR
2494 #define PATH_HAVE_FDOPENDIR 1
2495#else
2496 #define PATH_HAVE_FDOPENDIR 0
2497#endif
2498
2499#ifdef HAVE_FEXECVE
2500 #define PATH_HAVE_FEXECVE 1
2501#else
2502 #define PATH_HAVE_FEXECVE 0
2503#endif
2504
2505#ifdef HAVE_FPATHCONF
2506 #define PATH_HAVE_FPATHCONF 1
2507#else
2508 #define PATH_HAVE_FPATHCONF 0
2509#endif
2510
2511#ifdef HAVE_FSTATVFS
2512 #define PATH_HAVE_FSTATVFS 1
2513#else
2514 #define PATH_HAVE_FSTATVFS 0
2515#endif
2516
2517#ifdef HAVE_FTRUNCATE
2518 #define PATH_HAVE_FTRUNCATE 1
2519#else
2520 #define PATH_HAVE_FTRUNCATE 0
2521#endif
2522/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002523
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002524#ifdef MS_WINDOWS
2525 #undef PATH_HAVE_FTRUNCATE
2526 #define PATH_HAVE_FTRUNCATE 1
2527#endif
Larry Hastings31826802013-10-19 00:09:25 -07002528
Larry Hastings61272b72014-01-07 12:41:53 -08002529/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002530
2531class path_t_converter(CConverter):
2532
2533 type = "path_t"
2534 impl_by_reference = True
2535 parse_by_reference = True
2536
2537 converter = 'path_converter'
2538
2539 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002540 # right now path_t doesn't support default values.
2541 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002542 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002543 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002544
Larry Hastings2f936352014-08-05 14:04:04 +10002545 if self.c_default not in (None, 'Py_None'):
2546 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002547
2548 self.nullable = nullable
2549 self.allow_fd = allow_fd
2550
Larry Hastings7726ac92014-01-31 22:03:12 -08002551 def pre_render(self):
2552 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002553 if isinstance(value, str):
2554 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002555 return str(int(bool(value)))
2556
2557 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002558 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002559 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002560 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002561 strify(self.nullable),
2562 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002563 )
2564
2565 def cleanup(self):
2566 return "path_cleanup(&" + self.name + ");\n"
2567
2568
2569class dir_fd_converter(CConverter):
2570 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002571
Larry Hastings2f936352014-08-05 14:04:04 +10002572 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002573 if self.default in (unspecified, None):
2574 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002575 if isinstance(requires, str):
2576 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2577 else:
2578 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002579
Larry Hastings2f936352014-08-05 14:04:04 +10002580class fildes_converter(CConverter):
2581 type = 'int'
2582 converter = 'fildes_converter'
2583
2584class uid_t_converter(CConverter):
2585 type = "uid_t"
2586 converter = '_Py_Uid_Converter'
2587
2588class gid_t_converter(CConverter):
2589 type = "gid_t"
2590 converter = '_Py_Gid_Converter'
2591
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002592class dev_t_converter(CConverter):
2593 type = 'dev_t'
2594 converter = '_Py_Dev_Converter'
2595
2596class dev_t_return_converter(unsigned_long_return_converter):
2597 type = 'dev_t'
2598 conversion_fn = '_PyLong_FromDev'
2599 unsigned_cast = '(dev_t)'
2600
Larry Hastings2f936352014-08-05 14:04:04 +10002601class FSConverter_converter(CConverter):
2602 type = 'PyObject *'
2603 converter = 'PyUnicode_FSConverter'
2604 def converter_init(self):
2605 if self.default is not unspecified:
2606 fail("FSConverter_converter does not support default values")
2607 self.c_default = 'NULL'
2608
2609 def cleanup(self):
2610 return "Py_XDECREF(" + self.name + ");\n"
2611
2612class pid_t_converter(CConverter):
2613 type = 'pid_t'
2614 format_unit = '" _Py_PARSE_PID "'
2615
2616class idtype_t_converter(int_converter):
2617 type = 'idtype_t'
2618
2619class id_t_converter(CConverter):
2620 type = 'id_t'
2621 format_unit = '" _Py_PARSE_PID "'
2622
Benjamin Petersonca470632016-09-06 13:47:26 -07002623class intptr_t_converter(CConverter):
2624 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002625 format_unit = '" _Py_PARSE_INTPTR "'
2626
2627class Py_off_t_converter(CConverter):
2628 type = 'Py_off_t'
2629 converter = 'Py_off_t_converter'
2630
2631class Py_off_t_return_converter(long_return_converter):
2632 type = 'Py_off_t'
2633 conversion_fn = 'PyLong_FromPy_off_t'
2634
2635class path_confname_converter(CConverter):
2636 type="int"
2637 converter="conv_path_confname"
2638
2639class confstr_confname_converter(path_confname_converter):
2640 converter='conv_confstr_confname'
2641
2642class sysconf_confname_converter(path_confname_converter):
2643 converter="conv_sysconf_confname"
2644
Larry Hastings61272b72014-01-07 12:41:53 -08002645[python start generated code]*/
Victor Stinner1c2fa782020-05-10 11:05:29 +02002646/*[python end generated code: output=da39a3ee5e6b4b0d input=f1c8ae8d744f6c8b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002647
Larry Hastings61272b72014-01-07 12:41:53 -08002648/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002649
Larry Hastings2a727912014-01-16 11:32:01 -08002650os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002651
2652 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002653 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002654 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002655
2656 *
2657
Larry Hastings2f936352014-08-05 14:04:04 +10002658 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002659 If not None, it should be a file descriptor open to a directory,
2660 and path should be a relative string; path will then be relative to
2661 that directory.
2662
2663 follow_symlinks: bool = True
2664 If False, and the last element of the path is a symbolic link,
2665 stat will examine the symbolic link itself instead of the file
2666 the link points to.
2667
2668Perform a stat system call on the given path.
2669
2670dir_fd and follow_symlinks may not be implemented
2671 on your platform. If they are unavailable, using them will raise a
2672 NotImplementedError.
2673
2674It's an error to use dir_fd or follow_symlinks when specifying path as
2675 an open file descriptor.
2676
Larry Hastings61272b72014-01-07 12:41:53 -08002677[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002678
Larry Hastings31826802013-10-19 00:09:25 -07002679static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002680os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002681/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002682{
Victor Stinner1c2fa782020-05-10 11:05:29 +02002683 return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002684}
2685
Larry Hastings2f936352014-08-05 14:04:04 +10002686
2687/*[clinic input]
2688os.lstat
2689
2690 path : path_t
2691
2692 *
2693
2694 dir_fd : dir_fd(requires='fstatat') = None
2695
2696Perform a stat system call on the given path, without following symbolic links.
2697
2698Like stat(), but do not follow symbolic links.
2699Equivalent to stat(path, follow_symlinks=False).
2700[clinic start generated code]*/
2701
Larry Hastings2f936352014-08-05 14:04:04 +10002702static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002703os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2704/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002705{
2706 int follow_symlinks = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002707 return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10002708}
Larry Hastings31826802013-10-19 00:09:25 -07002709
Larry Hastings2f936352014-08-05 14:04:04 +10002710
Larry Hastings61272b72014-01-07 12:41:53 -08002711/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002712os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002713
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002714 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002715 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002716
2717 mode: int
2718 Operating-system mode bitfield. Can be F_OK to test existence,
2719 or the inclusive-OR of R_OK, W_OK, and X_OK.
2720
2721 *
2722
Larry Hastings2f936352014-08-05 14:04:04 +10002723 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002724 If not None, it should be a file descriptor open to a directory,
2725 and path should be relative; path will then be relative to that
2726 directory.
2727
2728 effective_ids: bool = False
2729 If True, access will use the effective uid/gid instead of
2730 the real uid/gid.
2731
2732 follow_symlinks: bool = True
2733 If False, and the last element of the path is a symbolic link,
2734 access will examine the symbolic link itself instead of the file
2735 the link points to.
2736
2737Use the real uid/gid to test for access to a path.
2738
2739{parameters}
2740dir_fd, effective_ids, and follow_symlinks may not be implemented
2741 on your platform. If they are unavailable, using them will raise a
2742 NotImplementedError.
2743
2744Note that most operations will use the effective uid/gid, therefore this
2745 routine can be used in a suid/sgid environment to test if the invoking user
2746 has the specified access to the path.
2747
Larry Hastings61272b72014-01-07 12:41:53 -08002748[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002749
Larry Hastings2f936352014-08-05 14:04:04 +10002750static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002751os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002752 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002753/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002754{
Larry Hastings2f936352014-08-05 14:04:04 +10002755 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002756
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002757#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002758 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002759#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002760 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002761#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002762
Larry Hastings9cf065c2012-06-22 16:30:09 -07002763#ifndef HAVE_FACCESSAT
2764 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002765 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002766
2767 if (effective_ids) {
2768 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002769 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002770 }
2771#endif
2772
2773#ifdef MS_WINDOWS
2774 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002775 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002776 Py_END_ALLOW_THREADS
2777
2778 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002779 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002780 * * we didn't get a -1, and
2781 * * write access wasn't requested,
2782 * * or the file isn't read-only,
2783 * * or it's a directory.
2784 * (Directories cannot be read-only on Windows.)
2785 */
Larry Hastings2f936352014-08-05 14:04:04 +10002786 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002787 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002789 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002790#else
2791
2792 Py_BEGIN_ALLOW_THREADS
2793#ifdef HAVE_FACCESSAT
2794 if ((dir_fd != DEFAULT_DIR_FD) ||
2795 effective_ids ||
2796 !follow_symlinks) {
2797 int flags = 0;
2798 if (!follow_symlinks)
2799 flags |= AT_SYMLINK_NOFOLLOW;
2800 if (effective_ids)
2801 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002802 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002803 }
2804 else
2805#endif
Larry Hastings31826802013-10-19 00:09:25 -07002806 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002807 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002808 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809#endif
2810
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002812}
2813
Guido van Rossumd371ff11999-01-25 16:12:23 +00002814#ifndef F_OK
2815#define F_OK 0
2816#endif
2817#ifndef R_OK
2818#define R_OK 4
2819#endif
2820#ifndef W_OK
2821#define W_OK 2
2822#endif
2823#ifndef X_OK
2824#define X_OK 1
2825#endif
2826
Larry Hastings31826802013-10-19 00:09:25 -07002827
Guido van Rossumd371ff11999-01-25 16:12:23 +00002828#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002829/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002830os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07002831
2832 fd: int
2833 Integer file descriptor handle.
2834
2835 /
2836
2837Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002838[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002839
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002840static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002841os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002842/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07002843{
Guido van Rossum94f6f721999-01-06 18:42:14 +00002844
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002845 long size = sysconf(_SC_TTY_NAME_MAX);
2846 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02002847 return posix_error();
2848 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02002849 char *buffer = (char *)PyMem_RawMalloc(size);
2850 if (buffer == NULL) {
2851 return PyErr_NoMemory();
2852 }
2853 int ret = ttyname_r(fd, buffer, size);
2854 if (ret != 0) {
2855 PyMem_RawFree(buffer);
2856 errno = ret;
2857 return posix_error();
2858 }
2859 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
2860 PyMem_RawFree(buffer);
2861 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002862}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002863#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002864
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002865#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002866/*[clinic input]
2867os.ctermid
2868
2869Return the name of the controlling terminal for this process.
2870[clinic start generated code]*/
2871
Larry Hastings2f936352014-08-05 14:04:04 +10002872static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002873os_ctermid_impl(PyObject *module)
2874/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002875{
Victor Stinner8c62be82010-05-06 00:08:46 +00002876 char *ret;
2877 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002878
Greg Wardb48bc172000-03-01 21:51:56 +00002879#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002880 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002881#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002882 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002883#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002884 if (ret == NULL)
2885 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002886 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002887}
Larry Hastings2f936352014-08-05 14:04:04 +10002888#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002889
Larry Hastings2f936352014-08-05 14:04:04 +10002890
2891/*[clinic input]
2892os.chdir
2893
2894 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2895
2896Change the current working directory to the specified path.
2897
2898path may always be specified as a string.
2899On some platforms, path may also be specified as an open file descriptor.
2900 If this functionality is unavailable, using it raises an exception.
2901[clinic start generated code]*/
2902
Larry Hastings2f936352014-08-05 14:04:04 +10002903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002904os_chdir_impl(PyObject *module, path_t *path)
2905/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002906{
2907 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002908
Saiyang Gou7514f4f2020-02-12 23:47:42 -08002909 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
2910 return NULL;
2911 }
2912
Larry Hastings9cf065c2012-06-22 16:30:09 -07002913 Py_BEGIN_ALLOW_THREADS
2914#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002915 /* on unix, success = 0, on windows, success = !0 */
2916 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002917#else
2918#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002919 if (path->fd != -1)
2920 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002921 else
2922#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002923 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002924#endif
2925 Py_END_ALLOW_THREADS
2926
2927 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002928 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002929 }
2930
Larry Hastings2f936352014-08-05 14:04:04 +10002931 Py_RETURN_NONE;
2932}
2933
2934
2935#ifdef HAVE_FCHDIR
2936/*[clinic input]
2937os.fchdir
2938
2939 fd: fildes
2940
2941Change to the directory of the given file descriptor.
2942
2943fd must be opened on a directory, not a file.
2944Equivalent to os.chdir(fd).
2945
2946[clinic start generated code]*/
2947
Fred Drake4d1e64b2002-04-15 19:40:07 +00002948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002949os_fchdir_impl(PyObject *module, int fd)
2950/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002951{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08002952 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
2953 return NULL;
2954 }
Larry Hastings2f936352014-08-05 14:04:04 +10002955 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002956}
2957#endif /* HAVE_FCHDIR */
2958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002959
Larry Hastings2f936352014-08-05 14:04:04 +10002960/*[clinic input]
2961os.chmod
2962
2963 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00002964 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002965 On some platforms, path may also be specified as an open file descriptor.
2966 If this functionality is unavailable, using it raises an exception.
2967
2968 mode: int
2969 Operating-system mode bitfield.
2970
2971 *
2972
2973 dir_fd : dir_fd(requires='fchmodat') = None
2974 If not None, it should be a file descriptor open to a directory,
2975 and path should be relative; path will then be relative to that
2976 directory.
2977
2978 follow_symlinks: bool = True
2979 If False, and the last element of the path is a symbolic link,
2980 chmod will modify the symbolic link itself instead of the file
2981 the link points to.
2982
2983Change the access permissions of a file.
2984
2985It is an error to use dir_fd or follow_symlinks when specifying path as
2986 an open file descriptor.
2987dir_fd and follow_symlinks may not be implemented on your platform.
2988 If they are unavailable, using them will raise a NotImplementedError.
2989
2990[clinic start generated code]*/
2991
Larry Hastings2f936352014-08-05 14:04:04 +10002992static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002993os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002994 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002995/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002996{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002997 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002998
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002999#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003000 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003001#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003002
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003#ifdef HAVE_FCHMODAT
3004 int fchmodat_nofollow_unsupported = 0;
3005#endif
3006
Larry Hastings9cf065c2012-06-22 16:30:09 -07003007#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3008 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003009 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010#endif
3011
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003012 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3013 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3014 return NULL;
3015 }
3016
Larry Hastings9cf065c2012-06-22 16:30:09 -07003017#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003018 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003019 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003020 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003021 result = 0;
3022 else {
3023 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003024 attr &= ~FILE_ATTRIBUTE_READONLY;
3025 else
3026 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003027 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003028 }
3029 Py_END_ALLOW_THREADS
3030
3031 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003032 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003033 }
3034#else /* MS_WINDOWS */
3035 Py_BEGIN_ALLOW_THREADS
3036#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003037 if (path->fd != -1)
3038 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003039 else
3040#endif
3041#ifdef HAVE_LCHMOD
3042 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003043 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003044 else
3045#endif
3046#ifdef HAVE_FCHMODAT
3047 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
3048 /*
3049 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3050 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003051 * and then says it isn't implemented yet.
3052 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003053 *
3054 * Once it is supported, os.chmod will automatically
3055 * support dir_fd and follow_symlinks=False. (Hopefully.)
3056 * Until then, we need to be careful what exception we raise.
3057 */
Larry Hastings2f936352014-08-05 14:04:04 +10003058 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003059 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3060 /*
3061 * But wait! We can't throw the exception without allowing threads,
3062 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3063 */
3064 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07003065 result &&
3066 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3067 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00003068 }
3069 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00003070#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003071 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003072 Py_END_ALLOW_THREADS
3073
3074 if (result) {
3075#ifdef HAVE_FCHMODAT
3076 if (fchmodat_nofollow_unsupported) {
3077 if (dir_fd != DEFAULT_DIR_FD)
3078 dir_fd_and_follow_symlinks_invalid("chmod",
3079 dir_fd, follow_symlinks);
3080 else
3081 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003082 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003083 }
3084 else
3085#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003086 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087 }
3088#endif
3089
Larry Hastings2f936352014-08-05 14:04:04 +10003090 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003091}
3092
Larry Hastings9cf065c2012-06-22 16:30:09 -07003093
Christian Heimes4e30a842007-11-30 22:12:06 +00003094#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003095/*[clinic input]
3096os.fchmod
3097
3098 fd: int
3099 mode: int
3100
3101Change the access permissions of the file given by file descriptor fd.
3102
3103Equivalent to os.chmod(fd, mode).
3104[clinic start generated code]*/
3105
Larry Hastings2f936352014-08-05 14:04:04 +10003106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003107os_fchmod_impl(PyObject *module, int fd, int mode)
3108/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003109{
3110 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003111 int async_err = 0;
3112
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003113 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3114 return NULL;
3115 }
3116
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003117 do {
3118 Py_BEGIN_ALLOW_THREADS
3119 res = fchmod(fd, mode);
3120 Py_END_ALLOW_THREADS
3121 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3122 if (res != 0)
3123 return (!async_err) ? posix_error() : NULL;
3124
Victor Stinner8c62be82010-05-06 00:08:46 +00003125 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003126}
3127#endif /* HAVE_FCHMOD */
3128
Larry Hastings2f936352014-08-05 14:04:04 +10003129
Christian Heimes4e30a842007-11-30 22:12:06 +00003130#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003131/*[clinic input]
3132os.lchmod
3133
3134 path: path_t
3135 mode: int
3136
3137Change the access permissions of a file, without following symbolic links.
3138
3139If path is a symlink, this affects the link itself rather than the target.
3140Equivalent to chmod(path, mode, follow_symlinks=False)."
3141[clinic start generated code]*/
3142
Larry Hastings2f936352014-08-05 14:04:04 +10003143static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003144os_lchmod_impl(PyObject *module, path_t *path, int mode)
3145/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003146{
Victor Stinner8c62be82010-05-06 00:08:46 +00003147 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003148 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3149 return NULL;
3150 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003151 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003152 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003153 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003154 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003155 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003156 return NULL;
3157 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003158 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003159}
3160#endif /* HAVE_LCHMOD */
3161
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003162
Thomas Wouterscf297e42007-02-23 15:07:44 +00003163#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003164/*[clinic input]
3165os.chflags
3166
3167 path: path_t
3168 flags: unsigned_long(bitwise=True)
3169 follow_symlinks: bool=True
3170
3171Set file flags.
3172
3173If follow_symlinks is False, and the last element of the path is a symbolic
3174 link, chflags will change flags on the symbolic link itself instead of the
3175 file the link points to.
3176follow_symlinks may not be implemented on your platform. If it is
3177unavailable, using it will raise a NotImplementedError.
3178
3179[clinic start generated code]*/
3180
Larry Hastings2f936352014-08-05 14:04:04 +10003181static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003182os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003183 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003184/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003185{
3186 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003187
3188#ifndef HAVE_LCHFLAGS
3189 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003190 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003191#endif
3192
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003193 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3194 return NULL;
3195 }
3196
Victor Stinner8c62be82010-05-06 00:08:46 +00003197 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003198#ifdef HAVE_LCHFLAGS
3199 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003200 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003201 else
3202#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003203 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003204 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003205
Larry Hastings2f936352014-08-05 14:04:04 +10003206 if (result)
3207 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003208
Larry Hastings2f936352014-08-05 14:04:04 +10003209 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003210}
3211#endif /* HAVE_CHFLAGS */
3212
Larry Hastings2f936352014-08-05 14:04:04 +10003213
Thomas Wouterscf297e42007-02-23 15:07:44 +00003214#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003215/*[clinic input]
3216os.lchflags
3217
3218 path: path_t
3219 flags: unsigned_long(bitwise=True)
3220
3221Set file flags.
3222
3223This function will not follow symbolic links.
3224Equivalent to chflags(path, flags, follow_symlinks=False).
3225[clinic start generated code]*/
3226
Larry Hastings2f936352014-08-05 14:04:04 +10003227static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003228os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3229/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003230{
Victor Stinner8c62be82010-05-06 00:08:46 +00003231 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003232 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3233 return NULL;
3234 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003236 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003237 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003238 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003239 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003240 }
Victor Stinner292c8352012-10-30 02:17:38 +01003241 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003242}
3243#endif /* HAVE_LCHFLAGS */
3244
Larry Hastings2f936352014-08-05 14:04:04 +10003245
Martin v. Löwis244edc82001-10-04 22:44:26 +00003246#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003247/*[clinic input]
3248os.chroot
3249 path: path_t
3250
3251Change root directory to path.
3252
3253[clinic start generated code]*/
3254
Larry Hastings2f936352014-08-05 14:04:04 +10003255static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003256os_chroot_impl(PyObject *module, path_t *path)
3257/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003258{
3259 int res;
3260 Py_BEGIN_ALLOW_THREADS
3261 res = chroot(path->narrow);
3262 Py_END_ALLOW_THREADS
3263 if (res < 0)
3264 return path_error(path);
3265 Py_RETURN_NONE;
3266}
3267#endif /* HAVE_CHROOT */
3268
Martin v. Löwis244edc82001-10-04 22:44:26 +00003269
Guido van Rossum21142a01999-01-08 21:05:37 +00003270#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003271/*[clinic input]
3272os.fsync
3273
3274 fd: fildes
3275
3276Force write of fd to disk.
3277[clinic start generated code]*/
3278
Larry Hastings2f936352014-08-05 14:04:04 +10003279static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003280os_fsync_impl(PyObject *module, int fd)
3281/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003282{
3283 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003284}
3285#endif /* HAVE_FSYNC */
3286
Larry Hastings2f936352014-08-05 14:04:04 +10003287
Ross Lagerwall7807c352011-03-17 20:20:30 +02003288#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003289/*[clinic input]
3290os.sync
3291
3292Force write of everything to disk.
3293[clinic start generated code]*/
3294
Larry Hastings2f936352014-08-05 14:04:04 +10003295static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003296os_sync_impl(PyObject *module)
3297/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003298{
3299 Py_BEGIN_ALLOW_THREADS
3300 sync();
3301 Py_END_ALLOW_THREADS
3302 Py_RETURN_NONE;
3303}
Larry Hastings2f936352014-08-05 14:04:04 +10003304#endif /* HAVE_SYNC */
3305
Ross Lagerwall7807c352011-03-17 20:20:30 +02003306
Guido van Rossum21142a01999-01-08 21:05:37 +00003307#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003308#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003309extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3310#endif
3311
Larry Hastings2f936352014-08-05 14:04:04 +10003312/*[clinic input]
3313os.fdatasync
3314
3315 fd: fildes
3316
3317Force write of fd to disk without forcing update of metadata.
3318[clinic start generated code]*/
3319
Larry Hastings2f936352014-08-05 14:04:04 +10003320static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003321os_fdatasync_impl(PyObject *module, int fd)
3322/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003323{
3324 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003325}
3326#endif /* HAVE_FDATASYNC */
3327
3328
Fredrik Lundh10723342000-07-10 16:38:09 +00003329#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003330/*[clinic input]
3331os.chown
3332
3333 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003334 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003335
3336 uid: uid_t
3337
3338 gid: gid_t
3339
3340 *
3341
3342 dir_fd : dir_fd(requires='fchownat') = None
3343 If not None, it should be a file descriptor open to a directory,
3344 and path should be relative; path will then be relative to that
3345 directory.
3346
3347 follow_symlinks: bool = True
3348 If False, and the last element of the path is a symbolic link,
3349 stat will examine the symbolic link itself instead of the file
3350 the link points to.
3351
3352Change the owner and group id of path to the numeric uid and gid.\
3353
3354path may always be specified as a string.
3355On some platforms, path may also be specified as an open file descriptor.
3356 If this functionality is unavailable, using it raises an exception.
3357If dir_fd is not None, it should be a file descriptor open to a directory,
3358 and path should be relative; path will then be relative to that directory.
3359If follow_symlinks is False, and the last element of the path is a symbolic
3360 link, chown will modify the symbolic link itself instead of the file the
3361 link points to.
3362It is an error to use dir_fd or follow_symlinks when specifying path as
3363 an open file descriptor.
3364dir_fd and follow_symlinks may not be implemented on your platform.
3365 If they are unavailable, using them will raise a NotImplementedError.
3366
3367[clinic start generated code]*/
3368
Larry Hastings2f936352014-08-05 14:04:04 +10003369static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003370os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003371 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003372/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003373{
3374 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375
3376#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3377 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003378 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003379#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003380 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3381 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3382 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003383
3384#ifdef __APPLE__
3385 /*
3386 * This is for Mac OS X 10.3, which doesn't have lchown.
3387 * (But we still have an lchown symbol because of weak-linking.)
3388 * It doesn't have fchownat either. So there's no possibility
3389 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003390 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 if ((!follow_symlinks) && (lchown == NULL)) {
3392 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003393 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003394 }
3395#endif
3396
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003397 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3398 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3399 return NULL;
3400 }
3401
Victor Stinner8c62be82010-05-06 00:08:46 +00003402 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003403#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003404 if (path->fd != -1)
3405 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003406 else
3407#endif
3408#ifdef HAVE_LCHOWN
3409 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003410 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411 else
3412#endif
3413#ifdef HAVE_FCHOWNAT
3414 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003415 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3417 else
3418#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003419 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003421
Larry Hastings2f936352014-08-05 14:04:04 +10003422 if (result)
3423 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003424
Larry Hastings2f936352014-08-05 14:04:04 +10003425 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003426}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003427#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003428
Larry Hastings2f936352014-08-05 14:04:04 +10003429
Christian Heimes4e30a842007-11-30 22:12:06 +00003430#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003431/*[clinic input]
3432os.fchown
3433
3434 fd: int
3435 uid: uid_t
3436 gid: gid_t
3437
3438Change the owner and group id of the file specified by file descriptor.
3439
3440Equivalent to os.chown(fd, uid, gid).
3441
3442[clinic start generated code]*/
3443
Larry Hastings2f936352014-08-05 14:04:04 +10003444static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003445os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3446/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003447{
Victor Stinner8c62be82010-05-06 00:08:46 +00003448 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003449 int async_err = 0;
3450
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003451 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3452 return NULL;
3453 }
3454
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003455 do {
3456 Py_BEGIN_ALLOW_THREADS
3457 res = fchown(fd, uid, gid);
3458 Py_END_ALLOW_THREADS
3459 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3460 if (res != 0)
3461 return (!async_err) ? posix_error() : NULL;
3462
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003464}
3465#endif /* HAVE_FCHOWN */
3466
Larry Hastings2f936352014-08-05 14:04:04 +10003467
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003468#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003469/*[clinic input]
3470os.lchown
3471
3472 path : path_t
3473 uid: uid_t
3474 gid: gid_t
3475
3476Change the owner and group id of path to the numeric uid and gid.
3477
3478This function will not follow symbolic links.
3479Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3480[clinic start generated code]*/
3481
Larry Hastings2f936352014-08-05 14:04:04 +10003482static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003483os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3484/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003485{
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003487 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3488 return NULL;
3489 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003491 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003493 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003494 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003495 }
Larry Hastings2f936352014-08-05 14:04:04 +10003496 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003497}
3498#endif /* HAVE_LCHOWN */
3499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003500
Barry Warsaw53699e91996-12-10 23:23:01 +00003501static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003502posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003503{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003504#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003505 wchar_t wbuf[MAXPATHLEN];
3506 wchar_t *wbuf2 = wbuf;
3507 DWORD len;
3508
3509 Py_BEGIN_ALLOW_THREADS
3510 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3511 /* If the buffer is large enough, len does not include the
3512 terminating \0. If the buffer is too small, len includes
3513 the space needed for the terminator. */
3514 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003515 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003516 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003517 }
Victor Stinner689830e2019-06-26 17:31:12 +02003518 else {
3519 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003520 }
Victor Stinner689830e2019-06-26 17:31:12 +02003521 if (wbuf2) {
3522 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 }
Victor Stinner689830e2019-06-26 17:31:12 +02003524 }
3525 Py_END_ALLOW_THREADS
3526
3527 if (!wbuf2) {
3528 PyErr_NoMemory();
3529 return NULL;
3530 }
3531 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003532 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003533 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003534 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003536
Victor Stinner689830e2019-06-26 17:31:12 +02003537 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3538 if (wbuf2 != wbuf) {
3539 PyMem_RawFree(wbuf2);
3540 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003541
Victor Stinner689830e2019-06-26 17:31:12 +02003542 if (use_bytes) {
3543 if (resobj == NULL) {
3544 return NULL;
3545 }
3546 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3547 }
3548
3549 return resobj;
3550#else
3551 const size_t chunk = 1024;
3552
3553 char *buf = NULL;
3554 char *cwd = NULL;
3555 size_t buflen = 0;
3556
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003558 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003559 char *newbuf;
3560 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3561 buflen += chunk;
3562 newbuf = PyMem_RawRealloc(buf, buflen);
3563 }
3564 else {
3565 newbuf = NULL;
3566 }
3567 if (newbuf == NULL) {
3568 PyMem_RawFree(buf);
3569 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003570 break;
3571 }
Victor Stinner689830e2019-06-26 17:31:12 +02003572 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003573
Victor Stinner4403d7d2015-04-25 00:16:10 +02003574 cwd = getcwd(buf, buflen);
3575 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003577
Victor Stinner689830e2019-06-26 17:31:12 +02003578 if (buf == NULL) {
3579 return PyErr_NoMemory();
3580 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003581 if (cwd == NULL) {
3582 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003583 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003584 }
3585
Victor Stinner689830e2019-06-26 17:31:12 +02003586 PyObject *obj;
3587 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003588 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003589 }
3590 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003591 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003592 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003593 PyMem_RawFree(buf);
3594
3595 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003596#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003597}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003598
Larry Hastings2f936352014-08-05 14:04:04 +10003599
3600/*[clinic input]
3601os.getcwd
3602
3603Return a unicode string representing the current working directory.
3604[clinic start generated code]*/
3605
Larry Hastings2f936352014-08-05 14:04:04 +10003606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003607os_getcwd_impl(PyObject *module)
3608/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003609{
3610 return posix_getcwd(0);
3611}
3612
Larry Hastings2f936352014-08-05 14:04:04 +10003613
3614/*[clinic input]
3615os.getcwdb
3616
3617Return a bytes string representing the current working directory.
3618[clinic start generated code]*/
3619
Larry Hastings2f936352014-08-05 14:04:04 +10003620static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003621os_getcwdb_impl(PyObject *module)
3622/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003623{
3624 return posix_getcwd(1);
3625}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003626
Larry Hastings2f936352014-08-05 14:04:04 +10003627
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3629#define HAVE_LINK 1
3630#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003631
Guido van Rossumb6775db1994-08-01 11:34:53 +00003632#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003633/*[clinic input]
3634
3635os.link
3636
3637 src : path_t
3638 dst : path_t
3639 *
3640 src_dir_fd : dir_fd = None
3641 dst_dir_fd : dir_fd = None
3642 follow_symlinks: bool = True
3643
3644Create a hard link to a file.
3645
3646If either src_dir_fd or dst_dir_fd is not None, it should be a file
3647 descriptor open to a directory, and the respective path string (src or dst)
3648 should be relative; the path will then be relative to that directory.
3649If follow_symlinks is False, and the last element of src is a symbolic
3650 link, link will create a link to the symbolic link itself instead of the
3651 file the link points to.
3652src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3653 platform. If they are unavailable, using them will raise a
3654 NotImplementedError.
3655[clinic start generated code]*/
3656
Larry Hastings2f936352014-08-05 14:04:04 +10003657static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003658os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003659 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003660/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003661{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003662#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003663 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003664#else
3665 int result;
3666#endif
3667
Larry Hastings9cf065c2012-06-22 16:30:09 -07003668#ifndef HAVE_LINKAT
3669 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3670 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003671 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003672 }
3673#endif
3674
Steve Dowercc16be82016-09-08 10:35:16 -07003675#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003676 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003677 PyErr_SetString(PyExc_NotImplementedError,
3678 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003679 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003680 }
Steve Dowercc16be82016-09-08 10:35:16 -07003681#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003682
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003683 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3684 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3685 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3686 return NULL;
3687 }
3688
Brian Curtin1b9df392010-11-24 20:24:31 +00003689#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003690 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003691 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003692 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003693
Larry Hastings2f936352014-08-05 14:04:04 +10003694 if (!result)
3695 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003696#else
3697 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003698#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003699 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3700 (dst_dir_fd != DEFAULT_DIR_FD) ||
3701 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003702 result = linkat(src_dir_fd, src->narrow,
3703 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003704 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3705 else
Steve Dowercc16be82016-09-08 10:35:16 -07003706#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003707 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003708 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003709
Larry Hastings2f936352014-08-05 14:04:04 +10003710 if (result)
3711 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003712#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003713
Larry Hastings2f936352014-08-05 14:04:04 +10003714 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003715}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003716#endif
3717
Brian Curtin1b9df392010-11-24 20:24:31 +00003718
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003719#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003720static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003721_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003722{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003723 PyObject *v;
3724 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3725 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003726 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003727 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003728 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003729 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003730
Steve Dowercc16be82016-09-08 10:35:16 -07003731 WIN32_FIND_DATAW wFileData;
3732 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003733
Steve Dowercc16be82016-09-08 10:35:16 -07003734 if (!path->wide) { /* Default arg: "." */
3735 po_wchars = L".";
3736 len = 1;
3737 } else {
3738 po_wchars = path->wide;
3739 len = wcslen(path->wide);
3740 }
3741 /* The +5 is so we can append "\\*.*\0" */
3742 wnamebuf = PyMem_New(wchar_t, len + 5);
3743 if (!wnamebuf) {
3744 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003745 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003746 }
Steve Dowercc16be82016-09-08 10:35:16 -07003747 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003748 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003749 wchar_t wch = wnamebuf[len-1];
3750 if (wch != SEP && wch != ALTSEP && wch != L':')
3751 wnamebuf[len++] = SEP;
3752 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003753 }
Steve Dowercc16be82016-09-08 10:35:16 -07003754 if ((list = PyList_New(0)) == NULL) {
3755 goto exit;
3756 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003757 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003758 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003759 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003760 if (hFindFile == INVALID_HANDLE_VALUE) {
3761 int error = GetLastError();
3762 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003763 goto exit;
3764 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003765 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003766 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003767 }
3768 do {
3769 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003770 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3771 wcscmp(wFileData.cFileName, L"..") != 0) {
3772 v = PyUnicode_FromWideChar(wFileData.cFileName,
3773 wcslen(wFileData.cFileName));
3774 if (path->narrow && v) {
3775 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3776 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003777 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003778 Py_DECREF(list);
3779 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003780 break;
3781 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003782 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003784 Py_DECREF(list);
3785 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003786 break;
3787 }
3788 Py_DECREF(v);
3789 }
3790 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003791 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003792 Py_END_ALLOW_THREADS
3793 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3794 it got to the end of the directory. */
3795 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003796 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003797 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003798 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003799 }
3800 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003801
Larry Hastings9cf065c2012-06-22 16:30:09 -07003802exit:
3803 if (hFindFile != INVALID_HANDLE_VALUE) {
3804 if (FindClose(hFindFile) == FALSE) {
3805 if (list != NULL) {
3806 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003807 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003808 }
3809 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003810 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003811 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003812
Larry Hastings9cf065c2012-06-22 16:30:09 -07003813 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003814} /* end of _listdir_windows_no_opendir */
3815
3816#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3817
3818static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003819_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003820{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003821 PyObject *v;
3822 DIR *dirp = NULL;
3823 struct dirent *ep;
3824 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003825#ifdef HAVE_FDOPENDIR
3826 int fd = -1;
3827#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003828
Victor Stinner8c62be82010-05-06 00:08:46 +00003829 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003830#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003831 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003832 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003833 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003834 if (fd == -1)
3835 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003836
Larry Hastingsfdaea062012-06-25 04:42:23 -07003837 return_str = 1;
3838
Larry Hastings9cf065c2012-06-22 16:30:09 -07003839 Py_BEGIN_ALLOW_THREADS
3840 dirp = fdopendir(fd);
3841 Py_END_ALLOW_THREADS
3842 }
3843 else
3844#endif
3845 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003846 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003847 if (path->narrow) {
3848 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003849 /* only return bytes if they specified a bytes-like object */
3850 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003851 }
3852 else {
3853 name = ".";
3854 return_str = 1;
3855 }
3856
Larry Hastings9cf065c2012-06-22 16:30:09 -07003857 Py_BEGIN_ALLOW_THREADS
3858 dirp = opendir(name);
3859 Py_END_ALLOW_THREADS
3860 }
3861
3862 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003863 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003864#ifdef HAVE_FDOPENDIR
3865 if (fd != -1) {
3866 Py_BEGIN_ALLOW_THREADS
3867 close(fd);
3868 Py_END_ALLOW_THREADS
3869 }
3870#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003871 goto exit;
3872 }
3873 if ((list = PyList_New(0)) == NULL) {
3874 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003875 }
3876 for (;;) {
3877 errno = 0;
3878 Py_BEGIN_ALLOW_THREADS
3879 ep = readdir(dirp);
3880 Py_END_ALLOW_THREADS
3881 if (ep == NULL) {
3882 if (errno == 0) {
3883 break;
3884 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003885 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003886 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003887 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003888 }
3889 }
3890 if (ep->d_name[0] == '.' &&
3891 (NAMLEN(ep) == 1 ||
3892 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3893 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003894 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003895 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3896 else
3897 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003898 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003899 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003900 break;
3901 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003902 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003904 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003905 break;
3906 }
3907 Py_DECREF(v);
3908 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003909
Larry Hastings9cf065c2012-06-22 16:30:09 -07003910exit:
3911 if (dirp != NULL) {
3912 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003913#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003914 if (fd > -1)
3915 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003916#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003917 closedir(dirp);
3918 Py_END_ALLOW_THREADS
3919 }
3920
Larry Hastings9cf065c2012-06-22 16:30:09 -07003921 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003922} /* end of _posix_listdir */
3923#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003924
Larry Hastings2f936352014-08-05 14:04:04 +10003925
3926/*[clinic input]
3927os.listdir
3928
3929 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3930
3931Return a list containing the names of the files in the directory.
3932
BNMetricsb9427072018-11-02 15:20:19 +00003933path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003934 the filenames returned will also be bytes; in all other circumstances
3935 the filenames returned will be str.
3936If path is None, uses the path='.'.
3937On some platforms, path may also be specified as an open file descriptor;\
3938 the file descriptor must refer to a directory.
3939 If this functionality is unavailable, using it raises NotImplementedError.
3940
3941The list is in arbitrary order. It does not include the special
3942entries '.' and '..' even if they are present in the directory.
3943
3944
3945[clinic start generated code]*/
3946
Larry Hastings2f936352014-08-05 14:04:04 +10003947static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003948os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00003949/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003950{
Steve Dower60419a72019-06-24 08:42:54 -07003951 if (PySys_Audit("os.listdir", "O",
3952 path->object ? path->object : Py_None) < 0) {
3953 return NULL;
3954 }
Larry Hastings2f936352014-08-05 14:04:04 +10003955#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3956 return _listdir_windows_no_opendir(path, NULL);
3957#else
3958 return _posix_listdir(path, NULL);
3959#endif
3960}
3961
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003962#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003963/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003964/*[clinic input]
3965os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003966
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003967 path: path_t
3968 /
3969
3970[clinic start generated code]*/
3971
3972static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003973os__getfullpathname_impl(PyObject *module, path_t *path)
3974/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003975{
Victor Stinner3939c322019-06-25 15:02:43 +02003976 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003977
Victor Stinner3939c322019-06-25 15:02:43 +02003978 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
3979 if (_Py_abspath(path->wide, &abspath) < 0) {
3980 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003981 }
Victor Stinner3939c322019-06-25 15:02:43 +02003982 if (abspath == NULL) {
3983 return PyErr_NoMemory();
3984 }
3985
3986 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
3987 PyMem_RawFree(abspath);
3988 if (str == NULL) {
3989 return NULL;
3990 }
3991 if (path->narrow) {
3992 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
3993 }
3994 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10003995}
Brian Curtind40e6f72010-07-08 21:39:08 +00003996
Brian Curtind25aef52011-06-13 15:16:04 -05003997
Larry Hastings2f936352014-08-05 14:04:04 +10003998/*[clinic input]
3999os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004000
Steve Dower23ad6d02018-02-22 10:39:10 -08004001 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004002 /
4003
4004A helper function for samepath on windows.
4005[clinic start generated code]*/
4006
Larry Hastings2f936352014-08-05 14:04:04 +10004007static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004008os__getfinalpathname_impl(PyObject *module, path_t *path)
4009/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004010{
4011 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004012 wchar_t buf[MAXPATHLEN], *target_path = buf;
4013 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004014 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004015 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004016
Steve Dower23ad6d02018-02-22 10:39:10 -08004017 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004018 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004019 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004020 0, /* desired access */
4021 0, /* share mode */
4022 NULL, /* security attributes */
4023 OPEN_EXISTING,
4024 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4025 FILE_FLAG_BACKUP_SEMANTICS,
4026 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004027 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004028
Steve Dower23ad6d02018-02-22 10:39:10 -08004029 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004030 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004031 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004032
4033 /* We have a good handle to the target, use it to determine the
4034 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004035 while (1) {
4036 Py_BEGIN_ALLOW_THREADS
4037 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4038 buf_size, VOLUME_NAME_DOS);
4039 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004040
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004041 if (!result_length) {
4042 result = win32_error_object("GetFinalPathNameByHandleW",
4043 path->object);
4044 goto cleanup;
4045 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004046
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004047 if (result_length < buf_size) {
4048 break;
4049 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004050
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004051 wchar_t *tmp;
4052 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4053 result_length * sizeof(*tmp));
4054 if (!tmp) {
4055 result = PyErr_NoMemory();
4056 goto cleanup;
4057 }
4058
4059 buf_size = result_length;
4060 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004061 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004062
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004063 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004064 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004065 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004066 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004067
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004068cleanup:
4069 if (target_path != buf) {
4070 PyMem_Free(target_path);
4071 }
4072 CloseHandle(hFile);
4073 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004074}
Brian Curtin62857742010-09-06 17:07:27 +00004075
Tim Golden6b528062013-08-01 12:44:00 +01004076
Larry Hastings2f936352014-08-05 14:04:04 +10004077/*[clinic input]
4078os._getvolumepathname
4079
Steve Dower23ad6d02018-02-22 10:39:10 -08004080 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004081
4082A helper function for ismount on Win32.
4083[clinic start generated code]*/
4084
Larry Hastings2f936352014-08-05 14:04:04 +10004085static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004086os__getvolumepathname_impl(PyObject *module, path_t *path)
4087/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004088{
4089 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004090 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004091 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004092 BOOL ret;
4093
Tim Golden6b528062013-08-01 12:44:00 +01004094 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004095 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004096
Victor Stinner850a18e2017-10-24 16:53:32 -07004097 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004098 PyErr_SetString(PyExc_OverflowError, "path too long");
4099 return NULL;
4100 }
4101
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004102 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004103 if (mountpath == NULL)
4104 return PyErr_NoMemory();
4105
4106 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004107 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004108 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004109 Py_END_ALLOW_THREADS
4110
4111 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004112 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004113 goto exit;
4114 }
4115 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004116 if (path->narrow)
4117 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004118
4119exit:
4120 PyMem_Free(mountpath);
4121 return result;
4122}
Tim Golden6b528062013-08-01 12:44:00 +01004123
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004124#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004125
Larry Hastings2f936352014-08-05 14:04:04 +10004126
4127/*[clinic input]
4128os.mkdir
4129
4130 path : path_t
4131
4132 mode: int = 0o777
4133
4134 *
4135
4136 dir_fd : dir_fd(requires='mkdirat') = None
4137
4138# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4139
4140Create a directory.
4141
4142If dir_fd is not None, it should be a file descriptor open to a directory,
4143 and path should be relative; path will then be relative to that directory.
4144dir_fd may not be implemented on your platform.
4145 If it is unavailable, using it will raise a NotImplementedError.
4146
4147The mode argument is ignored on Windows.
4148[clinic start generated code]*/
4149
Larry Hastings2f936352014-08-05 14:04:04 +10004150static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004151os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4152/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004153{
4154 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004155
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004156 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4157 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4158 return NULL;
4159 }
4160
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004161#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004162 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004163 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004165
Larry Hastings2f936352014-08-05 14:04:04 +10004166 if (!result)
4167 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004168#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004169 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004170#if HAVE_MKDIRAT
4171 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004172 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004173 else
4174#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004175#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004176 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004177#else
Larry Hastings2f936352014-08-05 14:04:04 +10004178 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004179#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004180 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004181 if (result < 0)
4182 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004183#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004184 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004185}
4186
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004187
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004188/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4189#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004190#include <sys/resource.h>
4191#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004192
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004193
4194#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004195/*[clinic input]
4196os.nice
4197
4198 increment: int
4199 /
4200
4201Add increment to the priority of process and return the new priority.
4202[clinic start generated code]*/
4203
Larry Hastings2f936352014-08-05 14:04:04 +10004204static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004205os_nice_impl(PyObject *module, int increment)
4206/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004207{
4208 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004209
Victor Stinner8c62be82010-05-06 00:08:46 +00004210 /* There are two flavours of 'nice': one that returns the new
4211 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004212 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004213 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004214
Victor Stinner8c62be82010-05-06 00:08:46 +00004215 If we are of the nice family that returns the new priority, we
4216 need to clear errno before the call, and check if errno is filled
4217 before calling posix_error() on a returnvalue of -1, because the
4218 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004219
Victor Stinner8c62be82010-05-06 00:08:46 +00004220 errno = 0;
4221 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004222#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004223 if (value == 0)
4224 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004225#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004226 if (value == -1 && errno != 0)
4227 /* either nice() or getpriority() returned an error */
4228 return posix_error();
4229 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004230}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004231#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004232
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004233
4234#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004235/*[clinic input]
4236os.getpriority
4237
4238 which: int
4239 who: int
4240
4241Return program scheduling priority.
4242[clinic start generated code]*/
4243
Larry Hastings2f936352014-08-05 14:04:04 +10004244static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004245os_getpriority_impl(PyObject *module, int which, int who)
4246/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004247{
4248 int retval;
4249
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004250 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004251 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004252 if (errno != 0)
4253 return posix_error();
4254 return PyLong_FromLong((long)retval);
4255}
4256#endif /* HAVE_GETPRIORITY */
4257
4258
4259#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004260/*[clinic input]
4261os.setpriority
4262
4263 which: int
4264 who: int
4265 priority: int
4266
4267Set program scheduling priority.
4268[clinic start generated code]*/
4269
Larry Hastings2f936352014-08-05 14:04:04 +10004270static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004271os_setpriority_impl(PyObject *module, int which, int who, int priority)
4272/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004273{
4274 int retval;
4275
4276 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004277 if (retval == -1)
4278 return posix_error();
4279 Py_RETURN_NONE;
4280}
4281#endif /* HAVE_SETPRIORITY */
4282
4283
Barry Warsaw53699e91996-12-10 23:23:01 +00004284static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004285internal_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 +00004286{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004287 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004288 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004289
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004290#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004291 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004292 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004293#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004294 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004295#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004296
Larry Hastings9cf065c2012-06-22 16:30:09 -07004297 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4298 (dst_dir_fd != DEFAULT_DIR_FD);
4299#ifndef HAVE_RENAMEAT
4300 if (dir_fd_specified) {
4301 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004302 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004303 }
4304#endif
4305
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004306 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4307 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4308 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4309 return NULL;
4310 }
4311
Larry Hastings9cf065c2012-06-22 16:30:09 -07004312#ifdef MS_WINDOWS
4313 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004314 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004315 Py_END_ALLOW_THREADS
4316
Larry Hastings2f936352014-08-05 14:04:04 +10004317 if (!result)
4318 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004319
4320#else
Steve Dowercc16be82016-09-08 10:35:16 -07004321 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4322 PyErr_Format(PyExc_ValueError,
4323 "%s: src and dst must be the same type", function_name);
4324 return NULL;
4325 }
4326
Larry Hastings9cf065c2012-06-22 16:30:09 -07004327 Py_BEGIN_ALLOW_THREADS
4328#ifdef HAVE_RENAMEAT
4329 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004330 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004331 else
4332#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004333 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004334 Py_END_ALLOW_THREADS
4335
Larry Hastings2f936352014-08-05 14:04:04 +10004336 if (result)
4337 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004338#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004339 Py_RETURN_NONE;
4340}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004341
Larry Hastings2f936352014-08-05 14:04:04 +10004342
4343/*[clinic input]
4344os.rename
4345
4346 src : path_t
4347 dst : path_t
4348 *
4349 src_dir_fd : dir_fd = None
4350 dst_dir_fd : dir_fd = None
4351
4352Rename a file or directory.
4353
4354If either src_dir_fd or dst_dir_fd is not None, it should be a file
4355 descriptor open to a directory, and the respective path string (src or dst)
4356 should be relative; the path will then be relative to that directory.
4357src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4358 If they are unavailable, using them will raise a NotImplementedError.
4359[clinic start generated code]*/
4360
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004361static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004362os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004363 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004364/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004365{
Larry Hastings2f936352014-08-05 14:04:04 +10004366 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004367}
4368
Larry Hastings2f936352014-08-05 14:04:04 +10004369
4370/*[clinic input]
4371os.replace = os.rename
4372
4373Rename a file or directory, overwriting the destination.
4374
4375If either src_dir_fd or dst_dir_fd is not None, it should be a file
4376 descriptor open to a directory, and the respective path string (src or dst)
4377 should be relative; the path will then be relative to that directory.
4378src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004379 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004380[clinic start generated code]*/
4381
Larry Hastings2f936352014-08-05 14:04:04 +10004382static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004383os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4384 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004385/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004386{
4387 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4388}
4389
4390
4391/*[clinic input]
4392os.rmdir
4393
4394 path: path_t
4395 *
4396 dir_fd: dir_fd(requires='unlinkat') = None
4397
4398Remove a directory.
4399
4400If dir_fd is not None, it should be a file descriptor open to a directory,
4401 and path should be relative; path will then be relative to that directory.
4402dir_fd may not be implemented on your platform.
4403 If it is unavailable, using it will raise a NotImplementedError.
4404[clinic start generated code]*/
4405
Larry Hastings2f936352014-08-05 14:04:04 +10004406static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004407os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4408/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004409{
4410 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004411
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004412 if (PySys_Audit("os.rmdir", "Oi", path->object,
4413 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4414 return NULL;
4415 }
4416
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004417 Py_BEGIN_ALLOW_THREADS
4418#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004419 /* Windows, success=1, UNIX, success=0 */
4420 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004421#else
4422#ifdef HAVE_UNLINKAT
4423 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004424 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004425 else
4426#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004427 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004428#endif
4429 Py_END_ALLOW_THREADS
4430
Larry Hastings2f936352014-08-05 14:04:04 +10004431 if (result)
4432 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004433
Larry Hastings2f936352014-08-05 14:04:04 +10004434 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004435}
4436
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004437
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004438#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004439#ifdef MS_WINDOWS
4440/*[clinic input]
4441os.system -> long
4442
4443 command: Py_UNICODE
4444
4445Execute the command in a subshell.
4446[clinic start generated code]*/
4447
Larry Hastings2f936352014-08-05 14:04:04 +10004448static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004449os_system_impl(PyObject *module, const Py_UNICODE *command)
4450/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004451{
4452 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004453
Steve Dowerfbe3c762019-10-18 00:52:15 -07004454 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004455 return -1;
4456 }
4457
Victor Stinner8c62be82010-05-06 00:08:46 +00004458 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004459 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004460 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004461 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004462 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004463 return result;
4464}
4465#else /* MS_WINDOWS */
4466/*[clinic input]
4467os.system -> long
4468
4469 command: FSConverter
4470
4471Execute the command in a subshell.
4472[clinic start generated code]*/
4473
Larry Hastings2f936352014-08-05 14:04:04 +10004474static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004475os_system_impl(PyObject *module, PyObject *command)
4476/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004477{
4478 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004479 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004480
Steve Dowerfbe3c762019-10-18 00:52:15 -07004481 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004482 return -1;
4483 }
4484
Larry Hastings2f936352014-08-05 14:04:04 +10004485 Py_BEGIN_ALLOW_THREADS
4486 result = system(bytes);
4487 Py_END_ALLOW_THREADS
4488 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004489}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004490#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004491#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004492
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004493
Larry Hastings2f936352014-08-05 14:04:04 +10004494/*[clinic input]
4495os.umask
4496
4497 mask: int
4498 /
4499
4500Set the current numeric umask and return the previous umask.
4501[clinic start generated code]*/
4502
Larry Hastings2f936352014-08-05 14:04:04 +10004503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004504os_umask_impl(PyObject *module, int mask)
4505/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004506{
4507 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004508 if (i < 0)
4509 return posix_error();
4510 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004511}
4512
Brian Curtind40e6f72010-07-08 21:39:08 +00004513#ifdef MS_WINDOWS
4514
4515/* override the default DeleteFileW behavior so that directory
4516symlinks can be removed with this function, the same as with
4517Unix symlinks */
4518BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4519{
4520 WIN32_FILE_ATTRIBUTE_DATA info;
4521 WIN32_FIND_DATAW find_data;
4522 HANDLE find_data_handle;
4523 int is_directory = 0;
4524 int is_link = 0;
4525
4526 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4527 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004528
Brian Curtind40e6f72010-07-08 21:39:08 +00004529 /* Get WIN32_FIND_DATA structure for the path to determine if
4530 it is a symlink */
4531 if(is_directory &&
4532 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4533 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4534
4535 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004536 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4537 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4538 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4539 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004540 FindClose(find_data_handle);
4541 }
4542 }
4543 }
4544
4545 if (is_directory && is_link)
4546 return RemoveDirectoryW(lpFileName);
4547
4548 return DeleteFileW(lpFileName);
4549}
4550#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004551
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004552
Larry Hastings2f936352014-08-05 14:04:04 +10004553/*[clinic input]
4554os.unlink
4555
4556 path: path_t
4557 *
4558 dir_fd: dir_fd(requires='unlinkat')=None
4559
4560Remove a file (same as remove()).
4561
4562If dir_fd is not None, it should be a file descriptor open to a directory,
4563 and path should be relative; path will then be relative to that directory.
4564dir_fd may not be implemented on your platform.
4565 If it is unavailable, using it will raise a NotImplementedError.
4566
4567[clinic start generated code]*/
4568
Larry Hastings2f936352014-08-05 14:04:04 +10004569static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004570os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4571/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004572{
4573 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004575 if (PySys_Audit("os.remove", "Oi", path->object,
4576 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4577 return NULL;
4578 }
4579
Larry Hastings9cf065c2012-06-22 16:30:09 -07004580 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004581 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004583 /* Windows, success=1, UNIX, success=0 */
4584 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586#ifdef HAVE_UNLINKAT
4587 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004588 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004589 else
4590#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004591 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004593 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594 Py_END_ALLOW_THREADS
4595
Larry Hastings2f936352014-08-05 14:04:04 +10004596 if (result)
4597 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598
Larry Hastings2f936352014-08-05 14:04:04 +10004599 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004600}
4601
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004602
Larry Hastings2f936352014-08-05 14:04:04 +10004603/*[clinic input]
4604os.remove = os.unlink
4605
4606Remove a file (same as unlink()).
4607
4608If dir_fd is not None, it should be a file descriptor open to a directory,
4609 and path should be relative; path will then be relative to that directory.
4610dir_fd may not be implemented on your platform.
4611 If it is unavailable, using it will raise a NotImplementedError.
4612[clinic start generated code]*/
4613
Larry Hastings2f936352014-08-05 14:04:04 +10004614static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004615os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4616/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004617{
4618 return os_unlink_impl(module, path, dir_fd);
4619}
4620
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004621
Larry Hastings605a62d2012-06-24 04:33:36 -07004622static PyStructSequence_Field uname_result_fields[] = {
4623 {"sysname", "operating system name"},
4624 {"nodename", "name of machine on network (implementation-defined)"},
4625 {"release", "operating system release"},
4626 {"version", "operating system version"},
4627 {"machine", "hardware identifier"},
4628 {NULL}
4629};
4630
4631PyDoc_STRVAR(uname_result__doc__,
4632"uname_result: Result from os.uname().\n\n\
4633This object may be accessed either as a tuple of\n\
4634 (sysname, nodename, release, version, machine),\n\
4635or via the attributes sysname, nodename, release, version, and machine.\n\
4636\n\
4637See os.uname for more information.");
4638
4639static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08004640 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07004641 uname_result__doc__, /* doc */
4642 uname_result_fields,
4643 5
4644};
4645
Larry Hastings605a62d2012-06-24 04:33:36 -07004646#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004647/*[clinic input]
4648os.uname
4649
4650Return an object identifying the current operating system.
4651
4652The object behaves like a named tuple with the following fields:
4653 (sysname, nodename, release, version, machine)
4654
4655[clinic start generated code]*/
4656
Larry Hastings2f936352014-08-05 14:04:04 +10004657static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004658os_uname_impl(PyObject *module)
4659/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004660{
Victor Stinner8c62be82010-05-06 00:08:46 +00004661 struct utsname u;
4662 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004663 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004664
Victor Stinner8c62be82010-05-06 00:08:46 +00004665 Py_BEGIN_ALLOW_THREADS
4666 res = uname(&u);
4667 Py_END_ALLOW_THREADS
4668 if (res < 0)
4669 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004670
Hai Shif707d942020-03-16 21:15:01 +08004671 PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08004672 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004673 if (value == NULL)
4674 return NULL;
4675
4676#define SET(i, field) \
4677 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004678 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004679 if (!o) { \
4680 Py_DECREF(value); \
4681 return NULL; \
4682 } \
4683 PyStructSequence_SET_ITEM(value, i, o); \
4684 } \
4685
4686 SET(0, u.sysname);
4687 SET(1, u.nodename);
4688 SET(2, u.release);
4689 SET(3, u.version);
4690 SET(4, u.machine);
4691
4692#undef SET
4693
4694 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004695}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004696#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004697
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004698
Larry Hastings9cf065c2012-06-22 16:30:09 -07004699
4700typedef struct {
4701 int now;
4702 time_t atime_s;
4703 long atime_ns;
4704 time_t mtime_s;
4705 long mtime_ns;
4706} utime_t;
4707
4708/*
Victor Stinner484df002014-10-09 13:52:31 +02004709 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004710 * they also intentionally leak the declaration of a pointer named "time"
4711 */
4712#define UTIME_TO_TIMESPEC \
4713 struct timespec ts[2]; \
4714 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004715 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004716 time = NULL; \
4717 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004718 ts[0].tv_sec = ut->atime_s; \
4719 ts[0].tv_nsec = ut->atime_ns; \
4720 ts[1].tv_sec = ut->mtime_s; \
4721 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722 time = ts; \
4723 } \
4724
4725#define UTIME_TO_TIMEVAL \
4726 struct timeval tv[2]; \
4727 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004728 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729 time = NULL; \
4730 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004731 tv[0].tv_sec = ut->atime_s; \
4732 tv[0].tv_usec = ut->atime_ns / 1000; \
4733 tv[1].tv_sec = ut->mtime_s; \
4734 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004735 time = tv; \
4736 } \
4737
4738#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004739 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004740 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004741 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742 time = NULL; \
4743 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004744 u.actime = ut->atime_s; \
4745 u.modtime = ut->mtime_s; \
4746 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747 }
4748
4749#define UTIME_TO_TIME_T \
4750 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004751 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004752 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 time = NULL; \
4754 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004755 timet[0] = ut->atime_s; \
4756 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004757 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 } \
4759
4760
Victor Stinner528a9ab2015-09-03 21:30:26 +02004761#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762
4763static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004764utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765{
4766#ifdef HAVE_UTIMENSAT
4767 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4768 UTIME_TO_TIMESPEC;
4769 return utimensat(dir_fd, path, time, flags);
4770#elif defined(HAVE_FUTIMESAT)
4771 UTIME_TO_TIMEVAL;
4772 /*
4773 * follow_symlinks will never be false here;
4774 * we only allow !follow_symlinks and dir_fd together
4775 * if we have utimensat()
4776 */
4777 assert(follow_symlinks);
4778 return futimesat(dir_fd, path, time);
4779#endif
4780}
4781
Larry Hastings2f936352014-08-05 14:04:04 +10004782 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4783#else
4784 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004785#endif
4786
Victor Stinner528a9ab2015-09-03 21:30:26 +02004787#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788
4789static int
Victor Stinner484df002014-10-09 13:52:31 +02004790utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004791{
4792#ifdef HAVE_FUTIMENS
4793 UTIME_TO_TIMESPEC;
4794 return futimens(fd, time);
4795#else
4796 UTIME_TO_TIMEVAL;
4797 return futimes(fd, time);
4798#endif
4799}
4800
Larry Hastings2f936352014-08-05 14:04:04 +10004801 #define PATH_UTIME_HAVE_FD 1
4802#else
4803 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804#endif
4805
Victor Stinner5ebae872015-09-22 01:29:33 +02004806#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4807# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4808#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809
Victor Stinner4552ced2015-09-21 22:37:15 +02004810#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811
4812static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004813utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004814{
4815#ifdef HAVE_UTIMENSAT
4816 UTIME_TO_TIMESPEC;
4817 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4818#else
4819 UTIME_TO_TIMEVAL;
4820 return lutimes(path, time);
4821#endif
4822}
4823
4824#endif
4825
4826#ifndef MS_WINDOWS
4827
4828static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004829utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004830{
4831#ifdef HAVE_UTIMENSAT
4832 UTIME_TO_TIMESPEC;
4833 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4834#elif defined(HAVE_UTIMES)
4835 UTIME_TO_TIMEVAL;
4836 return utimes(path, time);
4837#elif defined(HAVE_UTIME_H)
4838 UTIME_TO_UTIMBUF;
4839 return utime(path, time);
4840#else
4841 UTIME_TO_TIME_T;
4842 return utime(path, time);
4843#endif
4844}
4845
4846#endif
4847
Larry Hastings76ad59b2012-05-03 00:30:07 -07004848static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02004849split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004850{
4851 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004852 PyObject *divmod;
Victor Stinner1c2fa782020-05-10 11:05:29 +02004853 divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07004854 if (!divmod)
4855 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004856 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4857 PyErr_Format(PyExc_TypeError,
4858 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08004859 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03004860 goto exit;
4861 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004862 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4863 if ((*s == -1) && PyErr_Occurred())
4864 goto exit;
4865 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004866 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004867 goto exit;
4868
4869 result = 1;
4870exit:
4871 Py_XDECREF(divmod);
4872 return result;
4873}
4874
Larry Hastings2f936352014-08-05 14:04:04 +10004875
4876/*[clinic input]
4877os.utime
4878
4879 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004880 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10004881 *
4882 ns: object = NULL
4883 dir_fd: dir_fd(requires='futimensat') = None
4884 follow_symlinks: bool=True
4885
Martin Panter0ff89092015-09-09 01:56:53 +00004886# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004887
4888Set the access and modified time of path.
4889
4890path may always be specified as a string.
4891On some platforms, path may also be specified as an open file descriptor.
4892 If this functionality is unavailable, using it raises an exception.
4893
4894If times is not None, it must be a tuple (atime, mtime);
4895 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004896If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004897 atime_ns and mtime_ns should be expressed as integer nanoseconds
4898 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004899If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004900Specifying tuples for both times and ns is an error.
4901
4902If dir_fd is not None, it should be a file descriptor open to a directory,
4903 and path should be relative; path will then be relative to that directory.
4904If follow_symlinks is False, and the last element of the path is a symbolic
4905 link, utime will modify the symbolic link itself instead of the file the
4906 link points to.
4907It is an error to use dir_fd or follow_symlinks when specifying path
4908 as an open file descriptor.
4909dir_fd and follow_symlinks may not be available on your platform.
4910 If they are unavailable, using them will raise a NotImplementedError.
4911
4912[clinic start generated code]*/
4913
Larry Hastings2f936352014-08-05 14:04:04 +10004914static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004915os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4916 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004917/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004918{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004919#ifdef MS_WINDOWS
4920 HANDLE hFile;
4921 FILETIME atime, mtime;
4922#else
4923 int result;
4924#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004925
Larry Hastings2f936352014-08-05 14:04:04 +10004926 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004927
Christian Heimesb3c87242013-08-01 00:08:16 +02004928 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004929
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004930 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004931 PyErr_SetString(PyExc_ValueError,
4932 "utime: you may specify either 'times'"
4933 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004934 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004935 }
4936
Serhiy Storchaka279f4462019-09-14 12:24:05 +03004937 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004938 time_t a_sec, m_sec;
4939 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004940 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004941 PyErr_SetString(PyExc_TypeError,
4942 "utime: 'times' must be either"
4943 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004944 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004945 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004947 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004948 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004949 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004950 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004951 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004952 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004953 utime.atime_s = a_sec;
4954 utime.atime_ns = a_nsec;
4955 utime.mtime_s = m_sec;
4956 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004957 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004958 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004959 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004960 PyErr_SetString(PyExc_TypeError,
4961 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004962 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004963 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004964 utime.now = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02004965 if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004966 &utime.atime_s, &utime.atime_ns) ||
Victor Stinner1c2fa782020-05-10 11:05:29 +02004967 !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004969 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004970 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004971 }
4972 else {
4973 /* times and ns are both None/unspecified. use "now". */
4974 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004975 }
4976
Victor Stinner4552ced2015-09-21 22:37:15 +02004977#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004978 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004979 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004980#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004981
Larry Hastings2f936352014-08-05 14:04:04 +10004982 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4983 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4984 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004985 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004986
Larry Hastings9cf065c2012-06-22 16:30:09 -07004987#if !defined(HAVE_UTIMENSAT)
4988 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004989 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004990 "utime: cannot use dir_fd and follow_symlinks "
4991 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02004992 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004993 }
4994#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004995
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004996 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
4997 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4998 return NULL;
4999 }
5000
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005001#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005002 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005003 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5004 NULL, OPEN_EXISTING,
5005 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005006 Py_END_ALLOW_THREADS
5007 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005008 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005009 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005010 }
5011
Larry Hastings9cf065c2012-06-22 16:30:09 -07005012 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005013 GetSystemTimeAsFileTime(&mtime);
5014 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005015 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005016 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005017 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5018 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005019 }
5020 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5021 /* Avoid putting the file name into the error here,
5022 as that may confuse the user into believing that
5023 something is wrong with the file, when it also
5024 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005025 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005026 CloseHandle(hFile);
5027 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005029 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005030#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005031 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005032
Victor Stinner4552ced2015-09-21 22:37:15 +02005033#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005034 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005035 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005036 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005037#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005038
Victor Stinner528a9ab2015-09-03 21:30:26 +02005039#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005040 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10005041 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005042 else
5043#endif
5044
Victor Stinner528a9ab2015-09-03 21:30:26 +02005045#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005046 if (path->fd != -1)
5047 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005048 else
5049#endif
5050
Larry Hastings2f936352014-08-05 14:04:04 +10005051 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005052
5053 Py_END_ALLOW_THREADS
5054
5055 if (result < 0) {
5056 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005057 posix_error();
5058 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005060
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005061#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005062
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005063 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005064}
5065
Guido van Rossum3b066191991-06-04 19:40:25 +00005066/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005067
Larry Hastings2f936352014-08-05 14:04:04 +10005068
5069/*[clinic input]
5070os._exit
5071
5072 status: int
5073
5074Exit to the system with specified status, without normal exit processing.
5075[clinic start generated code]*/
5076
Larry Hastings2f936352014-08-05 14:04:04 +10005077static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005078os__exit_impl(PyObject *module, int status)
5079/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005080{
5081 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005082 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005083}
5084
Steve Dowercc16be82016-09-08 10:35:16 -07005085#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5086#define EXECV_CHAR wchar_t
5087#else
5088#define EXECV_CHAR char
5089#endif
5090
pxinwrf2d7ac72019-05-21 18:46:37 +08005091#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005092static void
Steve Dowercc16be82016-09-08 10:35:16 -07005093free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005094{
Victor Stinner8c62be82010-05-06 00:08:46 +00005095 Py_ssize_t i;
5096 for (i = 0; i < count; i++)
5097 PyMem_Free(array[i]);
5098 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005099}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005100
Berker Peksag81816462016-09-15 20:19:47 +03005101static int
5102fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005103{
Victor Stinner8c62be82010-05-06 00:08:46 +00005104 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005105 PyObject *ub;
5106 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005107#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005108 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005109 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005110 *out = PyUnicode_AsWideCharString(ub, &size);
5111 if (*out)
5112 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005113#else
Berker Peksag81816462016-09-15 20:19:47 +03005114 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005115 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005116 size = PyBytes_GET_SIZE(ub);
5117 *out = PyMem_Malloc(size + 1);
5118 if (*out) {
5119 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5120 result = 1;
5121 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005122 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005123#endif
Berker Peksag81816462016-09-15 20:19:47 +03005124 Py_DECREF(ub);
5125 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005126}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005127#endif
5128
pxinwrf2d7ac72019-05-21 18:46:37 +08005129#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005130static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005131parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5132{
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 Py_ssize_t i, pos, envc;
5134 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005135 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005136 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005137
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 i = PyMapping_Size(env);
5139 if (i < 0)
5140 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005141 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 if (envlist == NULL) {
5143 PyErr_NoMemory();
5144 return NULL;
5145 }
5146 envc = 0;
5147 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005148 if (!keys)
5149 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005150 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005151 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005152 goto error;
5153 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5154 PyErr_Format(PyExc_TypeError,
5155 "env.keys() or env.values() is not a list");
5156 goto error;
5157 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005158
Victor Stinner8c62be82010-05-06 00:08:46 +00005159 for (pos = 0; pos < i; pos++) {
5160 key = PyList_GetItem(keys, pos);
5161 val = PyList_GetItem(vals, pos);
5162 if (!key || !val)
5163 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005164
Berker Peksag81816462016-09-15 20:19:47 +03005165#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5166 if (!PyUnicode_FSDecoder(key, &key2))
5167 goto error;
5168 if (!PyUnicode_FSDecoder(val, &val2)) {
5169 Py_DECREF(key2);
5170 goto error;
5171 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005172 /* Search from index 1 because on Windows starting '=' is allowed for
5173 defining hidden environment variables. */
5174 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5175 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5176 {
5177 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005178 Py_DECREF(key2);
5179 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005180 goto error;
5181 }
Berker Peksag81816462016-09-15 20:19:47 +03005182 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5183#else
5184 if (!PyUnicode_FSConverter(key, &key2))
5185 goto error;
5186 if (!PyUnicode_FSConverter(val, &val2)) {
5187 Py_DECREF(key2);
5188 goto error;
5189 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005190 if (PyBytes_GET_SIZE(key2) == 0 ||
5191 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5192 {
5193 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005194 Py_DECREF(key2);
5195 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005196 goto error;
5197 }
Berker Peksag81816462016-09-15 20:19:47 +03005198 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5199 PyBytes_AS_STRING(val2));
5200#endif
5201 Py_DECREF(key2);
5202 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005203 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005204 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005205
5206 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5207 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005208 goto error;
5209 }
Berker Peksag81816462016-09-15 20:19:47 +03005210
Steve Dowercc16be82016-09-08 10:35:16 -07005211 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005212 }
5213 Py_DECREF(vals);
5214 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005215
Victor Stinner8c62be82010-05-06 00:08:46 +00005216 envlist[envc] = 0;
5217 *envc_ptr = envc;
5218 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005219
5220error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 Py_XDECREF(keys);
5222 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005223 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005225}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005226
Steve Dowercc16be82016-09-08 10:35:16 -07005227static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005228parse_arglist(PyObject* argv, Py_ssize_t *argc)
5229{
5230 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005231 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005232 if (argvlist == NULL) {
5233 PyErr_NoMemory();
5234 return NULL;
5235 }
5236 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005237 PyObject* item = PySequence_ITEM(argv, i);
5238 if (item == NULL)
5239 goto fail;
5240 if (!fsconvert_strdup(item, &argvlist[i])) {
5241 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005242 goto fail;
5243 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005244 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005245 }
5246 argvlist[*argc] = NULL;
5247 return argvlist;
5248fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005249 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005250 free_string_array(argvlist, *argc);
5251 return NULL;
5252}
Steve Dowercc16be82016-09-08 10:35:16 -07005253
Ross Lagerwall7807c352011-03-17 20:20:30 +02005254#endif
5255
Larry Hastings2f936352014-08-05 14:04:04 +10005256
Ross Lagerwall7807c352011-03-17 20:20:30 +02005257#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005258/*[clinic input]
5259os.execv
5260
Steve Dowercc16be82016-09-08 10:35:16 -07005261 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005262 Path of executable file.
5263 argv: object
5264 Tuple or list of strings.
5265 /
5266
5267Execute an executable path with arguments, replacing current process.
5268[clinic start generated code]*/
5269
Larry Hastings2f936352014-08-05 14:04:04 +10005270static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005271os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5272/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005273{
Steve Dowercc16be82016-09-08 10:35:16 -07005274 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005275 Py_ssize_t argc;
5276
5277 /* execv has two arguments: (path, argv), where
5278 argv is a list or tuple of strings. */
5279
Ross Lagerwall7807c352011-03-17 20:20:30 +02005280 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5281 PyErr_SetString(PyExc_TypeError,
5282 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005283 return NULL;
5284 }
5285 argc = PySequence_Size(argv);
5286 if (argc < 1) {
5287 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005288 return NULL;
5289 }
5290
5291 argvlist = parse_arglist(argv, &argc);
5292 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005293 return NULL;
5294 }
Steve Dowerbce26262016-11-19 19:17:26 -08005295 if (!argvlist[0][0]) {
5296 PyErr_SetString(PyExc_ValueError,
5297 "execv() arg 2 first element cannot be empty");
5298 free_string_array(argvlist, argc);
5299 return NULL;
5300 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005301
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005302 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005303 free_string_array(argvlist, argc);
5304 return NULL;
5305 }
5306
Steve Dowerbce26262016-11-19 19:17:26 -08005307 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005308#ifdef HAVE_WEXECV
5309 _wexecv(path->wide, argvlist);
5310#else
5311 execv(path->narrow, argvlist);
5312#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005313 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005314
5315 /* If we get here it's definitely an error */
5316
5317 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005318 return posix_error();
5319}
5320
Larry Hastings2f936352014-08-05 14:04:04 +10005321
5322/*[clinic input]
5323os.execve
5324
5325 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5326 Path of executable file.
5327 argv: object
5328 Tuple or list of strings.
5329 env: object
5330 Dictionary of strings mapping to strings.
5331
5332Execute an executable path with arguments, replacing current process.
5333[clinic start generated code]*/
5334
Larry Hastings2f936352014-08-05 14:04:04 +10005335static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005336os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5337/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005338{
Steve Dowercc16be82016-09-08 10:35:16 -07005339 EXECV_CHAR **argvlist = NULL;
5340 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005341 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005342
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 /* execve has three arguments: (path, argv, env), where
5344 argv is a list or tuple of strings and env is a dictionary
5345 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005346
Ross Lagerwall7807c352011-03-17 20:20:30 +02005347 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005348 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005349 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005350 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005351 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005352 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005353 if (argc < 1) {
5354 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5355 return NULL;
5356 }
5357
Victor Stinner8c62be82010-05-06 00:08:46 +00005358 if (!PyMapping_Check(env)) {
5359 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005360 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005361 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005362 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005363
Ross Lagerwall7807c352011-03-17 20:20:30 +02005364 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005365 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005366 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005367 }
Steve Dowerbce26262016-11-19 19:17:26 -08005368 if (!argvlist[0][0]) {
5369 PyErr_SetString(PyExc_ValueError,
5370 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005371 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005372 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005373
Victor Stinner8c62be82010-05-06 00:08:46 +00005374 envlist = parse_envlist(env, &envc);
5375 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005376 goto fail_0;
5377
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005378 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005379 goto fail_1;
5380 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005381
Steve Dowerbce26262016-11-19 19:17:26 -08005382 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005383#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005384 if (path->fd > -1)
5385 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005386 else
5387#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005388#ifdef HAVE_WEXECV
5389 _wexecve(path->wide, argvlist, envlist);
5390#else
Larry Hastings2f936352014-08-05 14:04:04 +10005391 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005392#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005393 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005394
5395 /* If we get here it's definitely an error */
5396
Alexey Izbyshev83460312018-10-20 03:28:22 +03005397 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005398 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005399 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005400 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005401 if (argvlist)
5402 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005403 return NULL;
5404}
Steve Dowercc16be82016-09-08 10:35:16 -07005405
Larry Hastings9cf065c2012-06-22 16:30:09 -07005406#endif /* HAVE_EXECV */
5407
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005408#ifdef HAVE_POSIX_SPAWN
5409
5410enum posix_spawn_file_actions_identifier {
5411 POSIX_SPAWN_OPEN,
5412 POSIX_SPAWN_CLOSE,
5413 POSIX_SPAWN_DUP2
5414};
5415
William Orr81574b82018-10-01 22:19:56 -07005416#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005417static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005418convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005419#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005420
5421static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005422parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005423 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005424 PyObject *setsigdef, PyObject *scheduler,
5425 posix_spawnattr_t *attrp)
5426{
5427 long all_flags = 0;
5428
5429 errno = posix_spawnattr_init(attrp);
5430 if (errno) {
5431 posix_error();
5432 return -1;
5433 }
5434
5435 if (setpgroup) {
5436 pid_t pgid = PyLong_AsPid(setpgroup);
5437 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5438 goto fail;
5439 }
5440 errno = posix_spawnattr_setpgroup(attrp, pgid);
5441 if (errno) {
5442 posix_error();
5443 goto fail;
5444 }
5445 all_flags |= POSIX_SPAWN_SETPGROUP;
5446 }
5447
5448 if (resetids) {
5449 all_flags |= POSIX_SPAWN_RESETIDS;
5450 }
5451
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005452 if (setsid) {
5453#ifdef POSIX_SPAWN_SETSID
5454 all_flags |= POSIX_SPAWN_SETSID;
5455#elif defined(POSIX_SPAWN_SETSID_NP)
5456 all_flags |= POSIX_SPAWN_SETSID_NP;
5457#else
5458 argument_unavailable_error(func_name, "setsid");
5459 return -1;
5460#endif
5461 }
5462
Pablo Galindo254a4662018-09-07 16:44:24 +01005463 if (setsigmask) {
5464 sigset_t set;
5465 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5466 goto fail;
5467 }
5468 errno = posix_spawnattr_setsigmask(attrp, &set);
5469 if (errno) {
5470 posix_error();
5471 goto fail;
5472 }
5473 all_flags |= POSIX_SPAWN_SETSIGMASK;
5474 }
5475
5476 if (setsigdef) {
5477 sigset_t set;
5478 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5479 goto fail;
5480 }
5481 errno = posix_spawnattr_setsigdefault(attrp, &set);
5482 if (errno) {
5483 posix_error();
5484 goto fail;
5485 }
5486 all_flags |= POSIX_SPAWN_SETSIGDEF;
5487 }
5488
5489 if (scheduler) {
5490#ifdef POSIX_SPAWN_SETSCHEDULER
5491 PyObject *py_schedpolicy;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005492 PyObject *schedparam_obj;
Pablo Galindo254a4662018-09-07 16:44:24 +01005493 struct sched_param schedparam;
5494
Victor Stinner1c2fa782020-05-10 11:05:29 +02005495 if (!PyArg_ParseTuple(scheduler, "OO"
Pablo Galindo254a4662018-09-07 16:44:24 +01005496 ";A scheduler tuple must have two elements",
Victor Stinner1c2fa782020-05-10 11:05:29 +02005497 &py_schedpolicy, &schedparam_obj)) {
5498 goto fail;
5499 }
5500 if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005501 goto fail;
5502 }
5503 if (py_schedpolicy != Py_None) {
5504 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5505
5506 if (schedpolicy == -1 && PyErr_Occurred()) {
5507 goto fail;
5508 }
5509 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5510 if (errno) {
5511 posix_error();
5512 goto fail;
5513 }
5514 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5515 }
5516 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5517 if (errno) {
5518 posix_error();
5519 goto fail;
5520 }
5521 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5522#else
5523 PyErr_SetString(PyExc_NotImplementedError,
5524 "The scheduler option is not supported in this system.");
5525 goto fail;
5526#endif
5527 }
5528
5529 errno = posix_spawnattr_setflags(attrp, all_flags);
5530 if (errno) {
5531 posix_error();
5532 goto fail;
5533 }
5534
5535 return 0;
5536
5537fail:
5538 (void)posix_spawnattr_destroy(attrp);
5539 return -1;
5540}
5541
5542static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005543parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005544 posix_spawn_file_actions_t *file_actionsp,
5545 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005546{
5547 PyObject *seq;
5548 PyObject *file_action = NULL;
5549 PyObject *tag_obj;
5550
5551 seq = PySequence_Fast(file_actions,
5552 "file_actions must be a sequence or None");
5553 if (seq == NULL) {
5554 return -1;
5555 }
5556
5557 errno = posix_spawn_file_actions_init(file_actionsp);
5558 if (errno) {
5559 posix_error();
5560 Py_DECREF(seq);
5561 return -1;
5562 }
5563
Zackery Spytzd52a83a2019-06-26 14:54:20 -06005564 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03005565 file_action = PySequence_Fast_GET_ITEM(seq, i);
5566 Py_INCREF(file_action);
5567 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5568 PyErr_SetString(PyExc_TypeError,
5569 "Each file_actions element must be a non-empty tuple");
5570 goto fail;
5571 }
5572 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5573 if (tag == -1 && PyErr_Occurred()) {
5574 goto fail;
5575 }
5576
5577 /* Populate the file_actions object */
5578 switch (tag) {
5579 case POSIX_SPAWN_OPEN: {
5580 int fd, oflag;
5581 PyObject *path;
5582 unsigned long mode;
5583 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5584 ";A open file_action tuple must have 5 elements",
5585 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5586 &oflag, &mode))
5587 {
5588 goto fail;
5589 }
Pablo Galindocb970732018-06-19 09:19:50 +01005590 if (PyList_Append(temp_buffer, path)) {
5591 Py_DECREF(path);
5592 goto fail;
5593 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005594 errno = posix_spawn_file_actions_addopen(file_actionsp,
5595 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005596 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005597 if (errno) {
5598 posix_error();
5599 goto fail;
5600 }
5601 break;
5602 }
5603 case POSIX_SPAWN_CLOSE: {
5604 int fd;
5605 if (!PyArg_ParseTuple(file_action, "Oi"
5606 ";A close file_action tuple must have 2 elements",
5607 &tag_obj, &fd))
5608 {
5609 goto fail;
5610 }
5611 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
5612 if (errno) {
5613 posix_error();
5614 goto fail;
5615 }
5616 break;
5617 }
5618 case POSIX_SPAWN_DUP2: {
5619 int fd1, fd2;
5620 if (!PyArg_ParseTuple(file_action, "Oii"
5621 ";A dup2 file_action tuple must have 3 elements",
5622 &tag_obj, &fd1, &fd2))
5623 {
5624 goto fail;
5625 }
5626 errno = posix_spawn_file_actions_adddup2(file_actionsp,
5627 fd1, fd2);
5628 if (errno) {
5629 posix_error();
5630 goto fail;
5631 }
5632 break;
5633 }
5634 default: {
5635 PyErr_SetString(PyExc_TypeError,
5636 "Unknown file_actions identifier");
5637 goto fail;
5638 }
5639 }
5640 Py_DECREF(file_action);
5641 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005642
Serhiy Storchakaef347532018-05-01 16:45:04 +03005643 Py_DECREF(seq);
5644 return 0;
5645
5646fail:
5647 Py_DECREF(seq);
5648 Py_DECREF(file_action);
5649 (void)posix_spawn_file_actions_destroy(file_actionsp);
5650 return -1;
5651}
5652
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005653
5654static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005655py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
5656 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005657 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005658 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005659{
Victor Stinner325e4ba2019-02-01 15:47:24 +01005660 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005661 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005662 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005663 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005664 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01005665 posix_spawnattr_t attr;
5666 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005667 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005668 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01005669 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03005670 pid_t pid;
5671 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005672
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005673 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03005674 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005675 like posix.environ. */
5676
Serhiy Storchakaef347532018-05-01 16:45:04 +03005677 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005678 PyErr_Format(PyExc_TypeError,
5679 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005680 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005681 }
5682 argc = PySequence_Size(argv);
5683 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005684 PyErr_Format(PyExc_ValueError,
5685 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005686 return NULL;
5687 }
5688
5689 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005690 PyErr_Format(PyExc_TypeError,
5691 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005692 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005693 }
5694
5695 argvlist = parse_arglist(argv, &argc);
5696 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005697 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005698 }
5699 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01005700 PyErr_Format(PyExc_ValueError,
5701 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005702 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005703 }
5704
5705 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005706 if (envlist == NULL) {
5707 goto exit;
5708 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005709
Anthony Shaw948ed8c2019-05-10 12:00:06 +10005710 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01005711 /* There is a bug in old versions of glibc that makes some of the
5712 * helper functions for manipulating file actions not copy the provided
5713 * buffers. The problem is that posix_spawn_file_actions_addopen does not
5714 * copy the value of path for some old versions of glibc (<2.20).
5715 * The use of temp_buffer here is a workaround that keeps the
5716 * python objects that own the buffers alive until posix_spawn gets called.
5717 * Check https://bugs.python.org/issue33630 and
5718 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
5719 temp_buffer = PyList_New(0);
5720 if (!temp_buffer) {
5721 goto exit;
5722 }
5723 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005724 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005725 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005726 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005727 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005728
Victor Stinner1c2fa782020-05-10 11:05:29 +02005729 if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005730 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005731 goto exit;
5732 }
5733 attrp = &attr;
5734
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005735 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005736 goto exit;
5737 }
5738
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005739 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005740#ifdef HAVE_POSIX_SPAWNP
5741 if (use_posix_spawnp) {
5742 err_code = posix_spawnp(&pid, path->narrow,
5743 file_actionsp, attrp, argvlist, envlist);
5744 }
5745 else
5746#endif /* HAVE_POSIX_SPAWNP */
5747 {
5748 err_code = posix_spawn(&pid, path->narrow,
5749 file_actionsp, attrp, argvlist, envlist);
5750 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005751 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005752
Serhiy Storchakaef347532018-05-01 16:45:04 +03005753 if (err_code) {
5754 errno = err_code;
5755 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005756 goto exit;
5757 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08005758#ifdef _Py_MEMORY_SANITIZER
5759 __msan_unpoison(&pid, sizeof(pid));
5760#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005761 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005762
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005763exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03005764 if (file_actionsp) {
5765 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005766 }
Pablo Galindo254a4662018-09-07 16:44:24 +01005767 if (attrp) {
5768 (void)posix_spawnattr_destroy(attrp);
5769 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005770 if (envlist) {
5771 free_string_array(envlist, envc);
5772 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005773 if (argvlist) {
5774 free_string_array(argvlist, argc);
5775 }
Pablo Galindocb970732018-06-19 09:19:50 +01005776 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00005777 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005778}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005779
5780
5781/*[clinic input]
5782
5783os.posix_spawn
5784 path: path_t
5785 Path of executable file.
5786 argv: object
5787 Tuple or list of strings.
5788 env: object
5789 Dictionary of strings mapping to strings.
5790 /
5791 *
5792 file_actions: object(c_default='NULL') = ()
5793 A sequence of file action tuples.
5794 setpgroup: object = NULL
5795 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5796 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005797 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
5798 setsid: bool(accept={int}) = False
5799 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005800 setsigmask: object(c_default='NULL') = ()
5801 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5802 setsigdef: object(c_default='NULL') = ()
5803 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5804 scheduler: object = NULL
5805 A tuple with the scheduler policy (optional) and parameters.
5806
5807Execute the program specified by path in a new process.
5808[clinic start generated code]*/
5809
5810static PyObject *
5811os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
5812 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005813 PyObject *setpgroup, int resetids, int setsid,
5814 PyObject *setsigmask, PyObject *setsigdef,
5815 PyObject *scheduler)
5816/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005817{
5818 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005819 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005820 scheduler);
5821}
5822 #endif /* HAVE_POSIX_SPAWN */
5823
5824
5825
5826#ifdef HAVE_POSIX_SPAWNP
5827/*[clinic input]
5828
5829os.posix_spawnp
5830 path: path_t
5831 Path of executable file.
5832 argv: object
5833 Tuple or list of strings.
5834 env: object
5835 Dictionary of strings mapping to strings.
5836 /
5837 *
5838 file_actions: object(c_default='NULL') = ()
5839 A sequence of file action tuples.
5840 setpgroup: object = NULL
5841 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
5842 resetids: bool(accept={int}) = False
5843 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005844 setsid: bool(accept={int}) = False
5845 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005846 setsigmask: object(c_default='NULL') = ()
5847 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
5848 setsigdef: object(c_default='NULL') = ()
5849 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
5850 scheduler: object = NULL
5851 A tuple with the scheduler policy (optional) and parameters.
5852
5853Execute the program specified by path in a new process.
5854[clinic start generated code]*/
5855
5856static PyObject *
5857os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
5858 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005859 PyObject *setpgroup, int resetids, int setsid,
5860 PyObject *setsigmask, PyObject *setsigdef,
5861 PyObject *scheduler)
5862/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005863{
5864 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005865 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03005866 scheduler);
5867}
5868#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005869
pxinwrf2d7ac72019-05-21 18:46:37 +08005870#ifdef HAVE_RTPSPAWN
5871static intptr_t
5872_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
5873 const char *envp[])
5874{
5875 RTP_ID rtpid;
5876 int status;
5877 pid_t res;
5878 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005879
pxinwrf2d7ac72019-05-21 18:46:37 +08005880 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
5881 uStackSize=0 cannot be used, the default stack size is too small for
5882 Python. */
5883 if (envp) {
5884 rtpid = rtpSpawn(rtpFileName, argv, envp,
5885 100, 0x1000000, 0, VX_FP_TASK);
5886 }
5887 else {
5888 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
5889 100, 0x1000000, 0, VX_FP_TASK);
5890 }
5891 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
5892 do {
5893 res = waitpid((pid_t)rtpid, &status, 0);
5894 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
5895
5896 if (res < 0)
5897 return RTP_ID_ERROR;
5898 return ((intptr_t)status);
5899 }
5900 return ((intptr_t)rtpid);
5901}
5902#endif
5903
5904#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10005905/*[clinic input]
5906os.spawnv
5907
5908 mode: int
5909 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005910 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005911 Path of executable file.
5912 argv: object
5913 Tuple or list of strings.
5914 /
5915
5916Execute the program specified by path in a new process.
5917[clinic start generated code]*/
5918
Larry Hastings2f936352014-08-05 14:04:04 +10005919static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005920os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5921/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005922{
Steve Dowercc16be82016-09-08 10:35:16 -07005923 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005924 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005926 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005927 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005928
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 /* spawnv has three arguments: (mode, path, argv), where
5930 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005931
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 if (PyList_Check(argv)) {
5933 argc = PyList_Size(argv);
5934 getitem = PyList_GetItem;
5935 }
5936 else if (PyTuple_Check(argv)) {
5937 argc = PyTuple_Size(argv);
5938 getitem = PyTuple_GetItem;
5939 }
5940 else {
5941 PyErr_SetString(PyExc_TypeError,
5942 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 return NULL;
5944 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005945 if (argc == 0) {
5946 PyErr_SetString(PyExc_ValueError,
5947 "spawnv() arg 2 cannot be empty");
5948 return NULL;
5949 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005950
Steve Dowercc16be82016-09-08 10:35:16 -07005951 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005952 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 return PyErr_NoMemory();
5954 }
5955 for (i = 0; i < argc; i++) {
5956 if (!fsconvert_strdup((*getitem)(argv, i),
5957 &argvlist[i])) {
5958 free_string_array(argvlist, i);
5959 PyErr_SetString(
5960 PyExc_TypeError,
5961 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 return NULL;
5963 }
Steve Dower93ff8722016-11-19 19:03:54 -08005964 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005965 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005966 PyErr_SetString(
5967 PyExc_ValueError,
5968 "spawnv() arg 2 first element cannot be empty");
5969 return NULL;
5970 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005971 }
5972 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005973
pxinwrf2d7ac72019-05-21 18:46:37 +08005974#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 if (mode == _OLD_P_OVERLAY)
5976 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08005977#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005978
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005979 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08005980 Py_None) < 0) {
5981 free_string_array(argvlist, argc);
5982 return NULL;
5983 }
5984
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005986 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005987#ifdef HAVE_WSPAWNV
5988 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08005989#elif defined(HAVE_RTPSPAWN)
5990 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07005991#else
5992 spawnval = _spawnv(mode, path->narrow, argvlist);
5993#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005994 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005996
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005998
Victor Stinner8c62be82010-05-06 00:08:46 +00005999 if (spawnval == -1)
6000 return posix_error();
6001 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006002 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006003}
6004
Larry Hastings2f936352014-08-05 14:04:04 +10006005/*[clinic input]
6006os.spawnve
6007
6008 mode: int
6009 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006010 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006011 Path of executable file.
6012 argv: object
6013 Tuple or list of strings.
6014 env: object
6015 Dictionary of strings mapping to strings.
6016 /
6017
6018Execute the program specified by path in a new process.
6019[clinic start generated code]*/
6020
Larry Hastings2f936352014-08-05 14:04:04 +10006021static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006022os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006023 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006024/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006025{
Steve Dowercc16be82016-09-08 10:35:16 -07006026 EXECV_CHAR **argvlist;
6027 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006029 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006030 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006032 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006033
Victor Stinner8c62be82010-05-06 00:08:46 +00006034 /* spawnve has four arguments: (mode, path, argv, env), where
6035 argv is a list or tuple of strings and env is a dictionary
6036 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006037
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 if (PyList_Check(argv)) {
6039 argc = PyList_Size(argv);
6040 getitem = PyList_GetItem;
6041 }
6042 else if (PyTuple_Check(argv)) {
6043 argc = PyTuple_Size(argv);
6044 getitem = PyTuple_GetItem;
6045 }
6046 else {
6047 PyErr_SetString(PyExc_TypeError,
6048 "spawnve() arg 2 must be a tuple or list");
6049 goto fail_0;
6050 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006051 if (argc == 0) {
6052 PyErr_SetString(PyExc_ValueError,
6053 "spawnve() arg 2 cannot be empty");
6054 goto fail_0;
6055 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006056 if (!PyMapping_Check(env)) {
6057 PyErr_SetString(PyExc_TypeError,
6058 "spawnve() arg 3 must be a mapping object");
6059 goto fail_0;
6060 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006061
Steve Dowercc16be82016-09-08 10:35:16 -07006062 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006063 if (argvlist == NULL) {
6064 PyErr_NoMemory();
6065 goto fail_0;
6066 }
6067 for (i = 0; i < argc; i++) {
6068 if (!fsconvert_strdup((*getitem)(argv, i),
6069 &argvlist[i]))
6070 {
6071 lastarg = i;
6072 goto fail_1;
6073 }
Steve Dowerbce26262016-11-19 19:17:26 -08006074 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006075 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006076 PyErr_SetString(
6077 PyExc_ValueError,
6078 "spawnv() arg 2 first element cannot be empty");
6079 goto fail_1;
6080 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006081 }
6082 lastarg = argc;
6083 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006084
Victor Stinner8c62be82010-05-06 00:08:46 +00006085 envlist = parse_envlist(env, &envc);
6086 if (envlist == NULL)
6087 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006088
pxinwrf2d7ac72019-05-21 18:46:37 +08006089#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006090 if (mode == _OLD_P_OVERLAY)
6091 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006092#endif
Tim Peters25059d32001-12-07 20:35:43 +00006093
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006094 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006095 goto fail_2;
6096 }
6097
Victor Stinner8c62be82010-05-06 00:08:46 +00006098 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006099 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006100#ifdef HAVE_WSPAWNV
6101 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006102#elif defined(HAVE_RTPSPAWN)
6103 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6104 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006105#else
6106 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6107#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006108 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006110
Victor Stinner8c62be82010-05-06 00:08:46 +00006111 if (spawnval == -1)
6112 (void) posix_error();
6113 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006114 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006115
Saiyang Gou95f60012020-02-04 16:15:00 -08006116 fail_2:
Victor Stinner8c62be82010-05-06 00:08:46 +00006117 while (--envc >= 0)
6118 PyMem_DEL(envlist[envc]);
6119 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006120 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006121 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006122 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006123 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006124}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006125
Guido van Rossuma1065681999-01-25 23:20:23 +00006126#endif /* HAVE_SPAWNV */
6127
6128
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006129#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006130
6131/* Helper function to validate arguments.
6132 Returns 0 on success. non-zero on failure with a TypeError raised.
6133 If obj is non-NULL it must be callable. */
6134static int
6135check_null_or_callable(PyObject *obj, const char* obj_name)
6136{
6137 if (obj && !PyCallable_Check(obj)) {
6138 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006139 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006140 return -1;
6141 }
6142 return 0;
6143}
6144
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006145/*[clinic input]
6146os.register_at_fork
6147
Gregory P. Smith163468a2017-05-29 10:03:41 -07006148 *
6149 before: object=NULL
6150 A callable to be called in the parent before the fork() syscall.
6151 after_in_child: object=NULL
6152 A callable to be called in the child after fork().
6153 after_in_parent: object=NULL
6154 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006155
Gregory P. Smith163468a2017-05-29 10:03:41 -07006156Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006157
Gregory P. Smith163468a2017-05-29 10:03:41 -07006158'before' callbacks are called in reverse order.
6159'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006160
6161[clinic start generated code]*/
6162
6163static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006164os_register_at_fork_impl(PyObject *module, PyObject *before,
6165 PyObject *after_in_child, PyObject *after_in_parent)
6166/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006167{
6168 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006169
Gregory P. Smith163468a2017-05-29 10:03:41 -07006170 if (!before && !after_in_child && !after_in_parent) {
6171 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6172 return NULL;
6173 }
6174 if (check_null_or_callable(before, "before") ||
6175 check_null_or_callable(after_in_child, "after_in_child") ||
6176 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006177 return NULL;
6178 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006179 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006180
Gregory P. Smith163468a2017-05-29 10:03:41 -07006181 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006182 return NULL;
6183 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006184 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006185 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006186 }
6187 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6188 return NULL;
6189 }
6190 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006191}
6192#endif /* HAVE_FORK */
6193
6194
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006195#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006196/*[clinic input]
6197os.fork1
6198
6199Fork a child process with a single multiplexed (i.e., not bound) thread.
6200
6201Return 0 to child process and PID of child to parent process.
6202[clinic start generated code]*/
6203
Larry Hastings2f936352014-08-05 14:04:04 +10006204static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006205os_fork1_impl(PyObject *module)
6206/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006207{
Victor Stinner8c62be82010-05-06 00:08:46 +00006208 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006209
Victor Stinner81a7be32020-04-14 15:14:01 +02006210 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006211 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6212 return NULL;
6213 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006214 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006215 pid = fork1();
6216 if (pid == 0) {
6217 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006218 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006219 } else {
6220 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006221 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 }
6223 if (pid == -1)
6224 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006225 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006226}
Larry Hastings2f936352014-08-05 14:04:04 +10006227#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006228
6229
Guido van Rossumad0ee831995-03-01 10:34:45 +00006230#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006231/*[clinic input]
6232os.fork
6233
6234Fork a child process.
6235
6236Return 0 to child process and PID of child to parent process.
6237[clinic start generated code]*/
6238
Larry Hastings2f936352014-08-05 14:04:04 +10006239static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006240os_fork_impl(PyObject *module)
6241/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006242{
Victor Stinner8c62be82010-05-06 00:08:46 +00006243 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006244 PyInterpreterState *interp = _PyInterpreterState_GET();
6245 if (interp->config._isolated_interpreter) {
6246 PyErr_SetString(PyExc_RuntimeError,
6247 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006248 return NULL;
6249 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006250 if (PySys_Audit("os.fork", NULL) < 0) {
6251 return NULL;
6252 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006253 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 pid = fork();
6255 if (pid == 0) {
6256 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006257 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 } else {
6259 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006260 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006261 }
6262 if (pid == -1)
6263 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006264 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006265}
Larry Hastings2f936352014-08-05 14:04:04 +10006266#endif /* HAVE_FORK */
6267
Guido van Rossum85e3b011991-06-03 12:42:10 +00006268
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006269#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006270#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006271/*[clinic input]
6272os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006273
Larry Hastings2f936352014-08-05 14:04:04 +10006274 policy: int
6275
6276Get the maximum scheduling priority for policy.
6277[clinic start generated code]*/
6278
Larry Hastings2f936352014-08-05 14:04:04 +10006279static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006280os_sched_get_priority_max_impl(PyObject *module, int policy)
6281/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006282{
6283 int max;
6284
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006285 max = sched_get_priority_max(policy);
6286 if (max < 0)
6287 return posix_error();
6288 return PyLong_FromLong(max);
6289}
6290
Larry Hastings2f936352014-08-05 14:04:04 +10006291
6292/*[clinic input]
6293os.sched_get_priority_min
6294
6295 policy: int
6296
6297Get the minimum scheduling priority for policy.
6298[clinic start generated code]*/
6299
Larry Hastings2f936352014-08-05 14:04:04 +10006300static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006301os_sched_get_priority_min_impl(PyObject *module, int policy)
6302/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006303{
6304 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006305 if (min < 0)
6306 return posix_error();
6307 return PyLong_FromLong(min);
6308}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006309#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6310
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006311
Larry Hastings2f936352014-08-05 14:04:04 +10006312#ifdef HAVE_SCHED_SETSCHEDULER
6313/*[clinic input]
6314os.sched_getscheduler
6315 pid: pid_t
6316 /
6317
Min ho Kimc4cacc82019-07-31 08:16:13 +10006318Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006319
6320Passing 0 for pid returns the scheduling policy for the calling process.
6321[clinic start generated code]*/
6322
Larry Hastings2f936352014-08-05 14:04:04 +10006323static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006324os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006325/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006326{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006327 int policy;
6328
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006329 policy = sched_getscheduler(pid);
6330 if (policy < 0)
6331 return posix_error();
6332 return PyLong_FromLong(policy);
6333}
Larry Hastings2f936352014-08-05 14:04:04 +10006334#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006335
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006336
William Orr81574b82018-10-01 22:19:56 -07006337#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006338/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006339class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006340
6341@classmethod
6342os.sched_param.__new__
6343
6344 sched_priority: object
6345 A scheduling parameter.
6346
Eddie Elizondob3966632019-11-05 07:16:14 -08006347Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006348[clinic start generated code]*/
6349
Larry Hastings2f936352014-08-05 14:04:04 +10006350static PyObject *
6351os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006352/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006353{
6354 PyObject *res;
6355
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006356 res = PyStructSequence_New(type);
6357 if (!res)
6358 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006359 Py_INCREF(sched_priority);
6360 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006361 return res;
6362}
6363
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006364PyDoc_VAR(os_sched_param__doc__);
6365
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006366static PyStructSequence_Field sched_param_fields[] = {
6367 {"sched_priority", "the scheduling priority"},
6368 {0}
6369};
6370
6371static PyStructSequence_Desc sched_param_desc = {
6372 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006373 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006374 sched_param_fields,
6375 1
6376};
6377
6378static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006379convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006380{
6381 long priority;
6382
Victor Stinner1c2fa782020-05-10 11:05:29 +02006383 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006384 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6385 return 0;
6386 }
6387 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6388 if (priority == -1 && PyErr_Occurred())
6389 return 0;
6390 if (priority > INT_MAX || priority < INT_MIN) {
6391 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6392 return 0;
6393 }
6394 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6395 return 1;
6396}
William Orr81574b82018-10-01 22:19:56 -07006397#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006398
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006399
6400#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006401/*[clinic input]
6402os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006403
Larry Hastings2f936352014-08-05 14:04:04 +10006404 pid: pid_t
6405 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006406 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006407 /
6408
6409Set the scheduling policy for the process identified by pid.
6410
6411If pid is 0, the calling process is changed.
6412param is an instance of sched_param.
6413[clinic start generated code]*/
6414
Larry Hastings2f936352014-08-05 14:04:04 +10006415static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006416os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006417 PyObject *param_obj)
6418/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006419{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006420 struct sched_param param;
6421 if (!convert_sched_param(module, param_obj, &param)) {
6422 return NULL;
6423 }
6424
Jesus Cea9c822272011-09-10 01:40:52 +02006425 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006426 ** sched_setscheduler() returns 0 in Linux, but the previous
6427 ** scheduling policy under Solaris/Illumos, and others.
6428 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006429 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006430 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006431 return posix_error();
6432 Py_RETURN_NONE;
6433}
Larry Hastings2f936352014-08-05 14:04:04 +10006434#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006435
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006436
6437#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006438/*[clinic input]
6439os.sched_getparam
6440 pid: pid_t
6441 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006442
Larry Hastings2f936352014-08-05 14:04:04 +10006443Returns scheduling parameters for the process identified by pid.
6444
6445If pid is 0, returns parameters for the calling process.
6446Return value is an instance of sched_param.
6447[clinic start generated code]*/
6448
Larry Hastings2f936352014-08-05 14:04:04 +10006449static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006450os_sched_getparam_impl(PyObject *module, pid_t pid)
6451/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006452{
6453 struct sched_param param;
6454 PyObject *result;
6455 PyObject *priority;
6456
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006457 if (sched_getparam(pid, &param))
6458 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006459 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006460 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006461 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006462 return NULL;
6463 priority = PyLong_FromLong(param.sched_priority);
6464 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006465 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006466 return NULL;
6467 }
Larry Hastings2f936352014-08-05 14:04:04 +10006468 PyStructSequence_SET_ITEM(result, 0, priority);
6469 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006470}
6471
Larry Hastings2f936352014-08-05 14:04:04 +10006472
6473/*[clinic input]
6474os.sched_setparam
6475 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006476 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006477 /
6478
6479Set scheduling parameters for the process identified by pid.
6480
6481If pid is 0, sets parameters for the calling process.
6482param should be an instance of sched_param.
6483[clinic start generated code]*/
6484
Larry Hastings2f936352014-08-05 14:04:04 +10006485static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006486os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6487/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006488{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006489 struct sched_param param;
6490 if (!convert_sched_param(module, param_obj, &param)) {
6491 return NULL;
6492 }
6493
6494 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006495 return posix_error();
6496 Py_RETURN_NONE;
6497}
Larry Hastings2f936352014-08-05 14:04:04 +10006498#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006499
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006500
6501#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006502/*[clinic input]
6503os.sched_rr_get_interval -> double
6504 pid: pid_t
6505 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006506
Larry Hastings2f936352014-08-05 14:04:04 +10006507Return the round-robin quantum for the process identified by pid, in seconds.
6508
6509Value returned is a float.
6510[clinic start generated code]*/
6511
Larry Hastings2f936352014-08-05 14:04:04 +10006512static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006513os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6514/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006515{
6516 struct timespec interval;
6517 if (sched_rr_get_interval(pid, &interval)) {
6518 posix_error();
6519 return -1.0;
6520 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006521#ifdef _Py_MEMORY_SANITIZER
6522 __msan_unpoison(&interval, sizeof(interval));
6523#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006524 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6525}
6526#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006527
Larry Hastings2f936352014-08-05 14:04:04 +10006528
6529/*[clinic input]
6530os.sched_yield
6531
6532Voluntarily relinquish the CPU.
6533[clinic start generated code]*/
6534
Larry Hastings2f936352014-08-05 14:04:04 +10006535static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006536os_sched_yield_impl(PyObject *module)
6537/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006538{
6539 if (sched_yield())
6540 return posix_error();
6541 Py_RETURN_NONE;
6542}
6543
Benjamin Peterson2740af82011-08-02 17:41:34 -05006544#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006545/* The minimum number of CPUs allocated in a cpu_set_t */
6546static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006547
Larry Hastings2f936352014-08-05 14:04:04 +10006548/*[clinic input]
6549os.sched_setaffinity
6550 pid: pid_t
6551 mask : object
6552 /
6553
6554Set the CPU affinity of the process identified by pid to mask.
6555
6556mask should be an iterable of integers identifying CPUs.
6557[clinic start generated code]*/
6558
Larry Hastings2f936352014-08-05 14:04:04 +10006559static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006560os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6561/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006562{
Antoine Pitrou84869872012-08-04 16:16:35 +02006563 int ncpus;
6564 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006565 cpu_set_t *cpu_set = NULL;
6566 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006567
Larry Hastings2f936352014-08-05 14:04:04 +10006568 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006569 if (iterator == NULL)
6570 return NULL;
6571
6572 ncpus = NCPUS_START;
6573 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006574 cpu_set = CPU_ALLOC(ncpus);
6575 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006576 PyErr_NoMemory();
6577 goto error;
6578 }
Larry Hastings2f936352014-08-05 14:04:04 +10006579 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006580
6581 while ((item = PyIter_Next(iterator))) {
6582 long cpu;
6583 if (!PyLong_Check(item)) {
6584 PyErr_Format(PyExc_TypeError,
6585 "expected an iterator of ints, "
6586 "but iterator yielded %R",
6587 Py_TYPE(item));
6588 Py_DECREF(item);
6589 goto error;
6590 }
6591 cpu = PyLong_AsLong(item);
6592 Py_DECREF(item);
6593 if (cpu < 0) {
6594 if (!PyErr_Occurred())
6595 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6596 goto error;
6597 }
6598 if (cpu > INT_MAX - 1) {
6599 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6600 goto error;
6601 }
6602 if (cpu >= ncpus) {
6603 /* Grow CPU mask to fit the CPU number */
6604 int newncpus = ncpus;
6605 cpu_set_t *newmask;
6606 size_t newsetsize;
6607 while (newncpus <= cpu) {
6608 if (newncpus > INT_MAX / 2)
6609 newncpus = cpu + 1;
6610 else
6611 newncpus = newncpus * 2;
6612 }
6613 newmask = CPU_ALLOC(newncpus);
6614 if (newmask == NULL) {
6615 PyErr_NoMemory();
6616 goto error;
6617 }
6618 newsetsize = CPU_ALLOC_SIZE(newncpus);
6619 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10006620 memcpy(newmask, cpu_set, setsize);
6621 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006622 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006623 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02006624 ncpus = newncpus;
6625 }
Larry Hastings2f936352014-08-05 14:04:04 +10006626 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006627 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07006628 if (PyErr_Occurred()) {
6629 goto error;
6630 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006631 Py_CLEAR(iterator);
6632
Larry Hastings2f936352014-08-05 14:04:04 +10006633 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006634 posix_error();
6635 goto error;
6636 }
Larry Hastings2f936352014-08-05 14:04:04 +10006637 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006638 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02006639
6640error:
Larry Hastings2f936352014-08-05 14:04:04 +10006641 if (cpu_set)
6642 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006643 Py_XDECREF(iterator);
6644 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006645}
6646
Larry Hastings2f936352014-08-05 14:04:04 +10006647
6648/*[clinic input]
6649os.sched_getaffinity
6650 pid: pid_t
6651 /
6652
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01006653Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10006654
6655The affinity is returned as a set of CPU identifiers.
6656[clinic start generated code]*/
6657
Larry Hastings2f936352014-08-05 14:04:04 +10006658static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006659os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03006660/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006661{
Antoine Pitrou84869872012-08-04 16:16:35 +02006662 int cpu, ncpus, count;
6663 size_t setsize;
6664 cpu_set_t *mask = NULL;
6665 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006666
Antoine Pitrou84869872012-08-04 16:16:35 +02006667 ncpus = NCPUS_START;
6668 while (1) {
6669 setsize = CPU_ALLOC_SIZE(ncpus);
6670 mask = CPU_ALLOC(ncpus);
6671 if (mask == NULL)
6672 return PyErr_NoMemory();
6673 if (sched_getaffinity(pid, setsize, mask) == 0)
6674 break;
6675 CPU_FREE(mask);
6676 if (errno != EINVAL)
6677 return posix_error();
6678 if (ncpus > INT_MAX / 2) {
6679 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6680 "a large enough CPU set");
6681 return NULL;
6682 }
6683 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006684 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006685
6686 res = PySet_New(NULL);
6687 if (res == NULL)
6688 goto error;
6689 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6690 if (CPU_ISSET_S(cpu, setsize, mask)) {
6691 PyObject *cpu_num = PyLong_FromLong(cpu);
6692 --count;
6693 if (cpu_num == NULL)
6694 goto error;
6695 if (PySet_Add(res, cpu_num)) {
6696 Py_DECREF(cpu_num);
6697 goto error;
6698 }
6699 Py_DECREF(cpu_num);
6700 }
6701 }
6702 CPU_FREE(mask);
6703 return res;
6704
6705error:
6706 if (mask)
6707 CPU_FREE(mask);
6708 Py_XDECREF(res);
6709 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006710}
6711
Benjamin Peterson2740af82011-08-02 17:41:34 -05006712#endif /* HAVE_SCHED_SETAFFINITY */
6713
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006714#endif /* HAVE_SCHED_H */
6715
Larry Hastings2f936352014-08-05 14:04:04 +10006716
Neal Norwitzb59798b2003-03-21 01:43:31 +00006717/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006718/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6719#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006720#define DEV_PTY_FILE "/dev/ptc"
6721#define HAVE_DEV_PTMX
6722#else
6723#define DEV_PTY_FILE "/dev/ptmx"
6724#endif
6725
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006726#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006727#ifdef HAVE_PTY_H
6728#include <pty.h>
6729#else
6730#ifdef HAVE_LIBUTIL_H
6731#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006732#else
6733#ifdef HAVE_UTIL_H
6734#include <util.h>
6735#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006736#endif /* HAVE_LIBUTIL_H */
6737#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006738#ifdef HAVE_STROPTS_H
6739#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006740#endif
ngie-eign7745ec42018-02-14 11:54:28 -08006741#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006742
Larry Hastings2f936352014-08-05 14:04:04 +10006743
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006744#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10006745/*[clinic input]
6746os.openpty
6747
6748Open a pseudo-terminal.
6749
6750Return a tuple of (master_fd, slave_fd) containing open file descriptors
6751for both the master and slave ends.
6752[clinic start generated code]*/
6753
Larry Hastings2f936352014-08-05 14:04:04 +10006754static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006755os_openpty_impl(PyObject *module)
6756/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006757{
Victor Stinnerdaf45552013-08-28 00:53:59 +02006758 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006759#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006761#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006762#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01006764#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00006765 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006766#endif
6767#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006768
Thomas Wouters70c21a12000-07-14 14:28:33 +00006769#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006771 goto posix_error;
6772
6773 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6774 goto error;
6775 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
6776 goto error;
6777
Neal Norwitzb59798b2003-03-21 01:43:31 +00006778#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6780 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006781 goto posix_error;
6782 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6783 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006784
Victor Stinnerdaf45552013-08-28 00:53:59 +02006785 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01006787 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02006788
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006789#else
Victor Stinner000de532013-11-25 23:19:58 +01006790 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006792 goto posix_error;
6793
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006795
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 /* change permission of slave */
6797 if (grantpt(master_fd) < 0) {
6798 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006799 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006801
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 /* unlock slave */
6803 if (unlockpt(master_fd) < 0) {
6804 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006805 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006807
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006809
Victor Stinner8c62be82010-05-06 00:08:46 +00006810 slave_name = ptsname(master_fd); /* get name of slave */
6811 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006812 goto posix_error;
6813
6814 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006815 if (slave_fd == -1)
6816 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006817
6818 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6819 goto posix_error;
6820
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006821#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6823 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006824#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006826#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006827#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006828#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006829
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006831
Victor Stinnerdaf45552013-08-28 00:53:59 +02006832posix_error:
6833 posix_error();
6834error:
6835 if (master_fd != -1)
6836 close(master_fd);
6837 if (slave_fd != -1)
6838 close(slave_fd);
6839 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006840}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006841#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006842
Larry Hastings2f936352014-08-05 14:04:04 +10006843
Fred Drake8cef4cf2000-06-28 16:40:38 +00006844#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006845/*[clinic input]
6846os.forkpty
6847
6848Fork a new process with a new pseudo-terminal as controlling tty.
6849
6850Returns a tuple of (pid, master_fd).
6851Like fork(), return pid of 0 to the child process,
6852and pid of child to the parent process.
6853To both, return fd of newly opened pseudo-terminal.
6854[clinic start generated code]*/
6855
Larry Hastings2f936352014-08-05 14:04:04 +10006856static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006857os_forkpty_impl(PyObject *module)
6858/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006859{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006860 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006862
Victor Stinner81a7be32020-04-14 15:14:01 +02006863 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006864 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6865 return NULL;
6866 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006867 if (PySys_Audit("os.forkpty", NULL) < 0) {
6868 return NULL;
6869 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006870 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 pid = forkpty(&master_fd, NULL, NULL, NULL);
6872 if (pid == 0) {
6873 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006874 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 } else {
6876 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006877 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 }
6879 if (pid == -1)
6880 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006882}
Larry Hastings2f936352014-08-05 14:04:04 +10006883#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006884
Ross Lagerwall7807c352011-03-17 20:20:30 +02006885
Guido van Rossumad0ee831995-03-01 10:34:45 +00006886#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006887/*[clinic input]
6888os.getegid
6889
6890Return the current process's effective group id.
6891[clinic start generated code]*/
6892
Larry Hastings2f936352014-08-05 14:04:04 +10006893static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006894os_getegid_impl(PyObject *module)
6895/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006896{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006897 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006898}
Larry Hastings2f936352014-08-05 14:04:04 +10006899#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006901
Guido van Rossumad0ee831995-03-01 10:34:45 +00006902#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006903/*[clinic input]
6904os.geteuid
6905
6906Return the current process's effective user id.
6907[clinic start generated code]*/
6908
Larry Hastings2f936352014-08-05 14:04:04 +10006909static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006910os_geteuid_impl(PyObject *module)
6911/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006912{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006913 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006914}
Larry Hastings2f936352014-08-05 14:04:04 +10006915#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006916
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006917
Guido van Rossumad0ee831995-03-01 10:34:45 +00006918#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006919/*[clinic input]
6920os.getgid
6921
6922Return the current process's group id.
6923[clinic start generated code]*/
6924
Larry Hastings2f936352014-08-05 14:04:04 +10006925static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006926os_getgid_impl(PyObject *module)
6927/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006928{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006929 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006930}
Larry Hastings2f936352014-08-05 14:04:04 +10006931#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006933
Berker Peksag39404992016-09-15 20:45:16 +03006934#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006935/*[clinic input]
6936os.getpid
6937
6938Return the current process id.
6939[clinic start generated code]*/
6940
Larry Hastings2f936352014-08-05 14:04:04 +10006941static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006942os_getpid_impl(PyObject *module)
6943/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006944{
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006946}
Berker Peksag39404992016-09-15 20:45:16 +03006947#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006948
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006949#ifdef NGROUPS_MAX
6950#define MAX_GROUPS NGROUPS_MAX
6951#else
6952 /* defined to be 16 on Solaris7, so this should be a small number */
6953#define MAX_GROUPS 64
6954#endif
6955
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006956#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006957
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006958#ifdef __APPLE__
6959/*[clinic input]
6960os.getgrouplist
6961
6962 user: str
6963 username to lookup
6964 group as basegid: int
6965 base group id of the user
6966 /
6967
6968Returns a list of groups to which a user belongs.
6969[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006970
6971static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006972os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
6973/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
6974#else
6975/*[clinic input]
6976os.getgrouplist
6977
6978 user: str
6979 username to lookup
6980 group as basegid: gid_t
6981 base group id of the user
6982 /
6983
6984Returns a list of groups to which a user belongs.
6985[clinic start generated code]*/
6986
6987static PyObject *
6988os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
6989/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
6990#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006991{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006992 int i, ngroups;
6993 PyObject *list;
6994#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006995 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006996#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03006997 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006998#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07006999
7000 /*
7001 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7002 * number of supplimental groups a users can belong to.
7003 * We have to increment it by one because
7004 * getgrouplist() returns both the supplemental groups
7005 * and the primary group, i.e. all of the groups the
7006 * user belongs to.
7007 */
7008 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007009
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007010 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007011#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007012 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007013#else
7014 groups = PyMem_New(gid_t, ngroups);
7015#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007016 if (groups == NULL) {
7017 return PyErr_NoMemory();
7018 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007019
7020 int old_ngroups = ngroups;
7021 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7022 /* Success */
7023 break;
7024 }
7025
7026 /* getgrouplist() fails if the group list is too small */
7027 PyMem_Free(groups);
7028
7029 if (ngroups > old_ngroups) {
7030 /* If the group list is too small, the glibc implementation of
7031 getgrouplist() sets ngroups to the total number of groups and
7032 returns -1. */
7033 }
7034 else {
7035 /* Double the group list size */
7036 if (ngroups > INT_MAX / 2) {
7037 return PyErr_NoMemory();
7038 }
7039 ngroups *= 2;
7040 }
7041
7042 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007043 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007044
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007045#ifdef _Py_MEMORY_SANITIZER
7046 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7047 __msan_unpoison(&ngroups, sizeof(ngroups));
7048 __msan_unpoison(groups, ngroups*sizeof(*groups));
7049#endif
7050
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007051 list = PyList_New(ngroups);
7052 if (list == NULL) {
7053 PyMem_Del(groups);
7054 return NULL;
7055 }
7056
7057 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007058#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007059 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007060#else
7061 PyObject *o = _PyLong_FromGid(groups[i]);
7062#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007063 if (o == NULL) {
7064 Py_DECREF(list);
7065 PyMem_Del(groups);
7066 return NULL;
7067 }
7068 PyList_SET_ITEM(list, i, o);
7069 }
7070
7071 PyMem_Del(groups);
7072
7073 return list;
7074}
Larry Hastings2f936352014-08-05 14:04:04 +10007075#endif /* HAVE_GETGROUPLIST */
7076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007077
Fred Drakec9680921999-12-13 16:37:25 +00007078#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007079/*[clinic input]
7080os.getgroups
7081
7082Return list of supplemental group IDs for the process.
7083[clinic start generated code]*/
7084
Larry Hastings2f936352014-08-05 14:04:04 +10007085static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007086os_getgroups_impl(PyObject *module)
7087/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007088{
7089 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007091
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007092 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007093 * This is a helper variable to store the intermediate result when
7094 * that happens.
7095 *
7096 * To keep the code readable the OSX behaviour is unconditional,
7097 * according to the POSIX spec this should be safe on all unix-y
7098 * systems.
7099 */
7100 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007101 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007102
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007103#ifdef __APPLE__
7104 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7105 * there are more groups than can fit in grouplist. Therefore, on OS X
7106 * always first call getgroups with length 0 to get the actual number
7107 * of groups.
7108 */
7109 n = getgroups(0, NULL);
7110 if (n < 0) {
7111 return posix_error();
7112 } else if (n <= MAX_GROUPS) {
7113 /* groups will fit in existing array */
7114 alt_grouplist = grouplist;
7115 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007116 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007117 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007118 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007119 }
7120 }
7121
7122 n = getgroups(n, alt_grouplist);
7123 if (n == -1) {
7124 if (alt_grouplist != grouplist) {
7125 PyMem_Free(alt_grouplist);
7126 }
7127 return posix_error();
7128 }
7129#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007130 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007131 if (n < 0) {
7132 if (errno == EINVAL) {
7133 n = getgroups(0, NULL);
7134 if (n == -1) {
7135 return posix_error();
7136 }
7137 if (n == 0) {
7138 /* Avoid malloc(0) */
7139 alt_grouplist = grouplist;
7140 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007141 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007142 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007143 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007144 }
7145 n = getgroups(n, alt_grouplist);
7146 if (n == -1) {
7147 PyMem_Free(alt_grouplist);
7148 return posix_error();
7149 }
7150 }
7151 } else {
7152 return posix_error();
7153 }
7154 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007155#endif
7156
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007157 result = PyList_New(n);
7158 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 int i;
7160 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007161 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007163 Py_DECREF(result);
7164 result = NULL;
7165 break;
Fred Drakec9680921999-12-13 16:37:25 +00007166 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007167 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007168 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007169 }
7170
7171 if (alt_grouplist != grouplist) {
7172 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007173 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007174
Fred Drakec9680921999-12-13 16:37:25 +00007175 return result;
7176}
Larry Hastings2f936352014-08-05 14:04:04 +10007177#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007178
Antoine Pitroub7572f02009-12-02 20:46:48 +00007179#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007180#ifdef __APPLE__
7181/*[clinic input]
7182os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007183
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007184 username as oname: FSConverter
7185 gid: int
7186 /
7187
7188Initialize the group access list.
7189
7190Call the system initgroups() to initialize the group access list with all of
7191the groups of which the specified username is a member, plus the specified
7192group id.
7193[clinic start generated code]*/
7194
Antoine Pitroub7572f02009-12-02 20:46:48 +00007195static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007196os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7197/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7198#else
7199/*[clinic input]
7200os.initgroups
7201
7202 username as oname: FSConverter
7203 gid: gid_t
7204 /
7205
7206Initialize the group access list.
7207
7208Call the system initgroups() to initialize the group access list with all of
7209the groups of which the specified username is a member, plus the specified
7210group id.
7211[clinic start generated code]*/
7212
7213static PyObject *
7214os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7215/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7216#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007217{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007218 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007219
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007220 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007221 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007222
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007223 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007224}
Larry Hastings2f936352014-08-05 14:04:04 +10007225#endif /* HAVE_INITGROUPS */
7226
Antoine Pitroub7572f02009-12-02 20:46:48 +00007227
Martin v. Löwis606edc12002-06-13 21:09:11 +00007228#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007229/*[clinic input]
7230os.getpgid
7231
7232 pid: pid_t
7233
7234Call the system call getpgid(), and return the result.
7235[clinic start generated code]*/
7236
Larry Hastings2f936352014-08-05 14:04:04 +10007237static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007238os_getpgid_impl(PyObject *module, pid_t pid)
7239/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007240{
7241 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007242 if (pgid < 0)
7243 return posix_error();
7244 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007245}
7246#endif /* HAVE_GETPGID */
7247
7248
Guido van Rossumb6775db1994-08-01 11:34:53 +00007249#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007250/*[clinic input]
7251os.getpgrp
7252
7253Return the current process group id.
7254[clinic start generated code]*/
7255
Larry Hastings2f936352014-08-05 14:04:04 +10007256static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007257os_getpgrp_impl(PyObject *module)
7258/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007259{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007260#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007261 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007262#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007263 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007264#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007265}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007266#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007268
Guido van Rossumb6775db1994-08-01 11:34:53 +00007269#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007270/*[clinic input]
7271os.setpgrp
7272
7273Make the current process the leader of its process group.
7274[clinic start generated code]*/
7275
Larry Hastings2f936352014-08-05 14:04:04 +10007276static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007277os_setpgrp_impl(PyObject *module)
7278/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007279{
Guido van Rossum64933891994-10-20 21:56:42 +00007280#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007281 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007282#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007283 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007284#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007285 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007286 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007287}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007288#endif /* HAVE_SETPGRP */
7289
Guido van Rossumad0ee831995-03-01 10:34:45 +00007290#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007291
7292#ifdef MS_WINDOWS
7293#include <tlhelp32.h>
7294
7295static PyObject*
7296win32_getppid()
7297{
7298 HANDLE snapshot;
7299 pid_t mypid;
7300 PyObject* result = NULL;
7301 BOOL have_record;
7302 PROCESSENTRY32 pe;
7303
7304 mypid = getpid(); /* This function never fails */
7305
7306 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7307 if (snapshot == INVALID_HANDLE_VALUE)
7308 return PyErr_SetFromWindowsErr(GetLastError());
7309
7310 pe.dwSize = sizeof(pe);
7311 have_record = Process32First(snapshot, &pe);
7312 while (have_record) {
7313 if (mypid == (pid_t)pe.th32ProcessID) {
7314 /* We could cache the ulong value in a static variable. */
7315 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7316 break;
7317 }
7318
7319 have_record = Process32Next(snapshot, &pe);
7320 }
7321
7322 /* If our loop exits and our pid was not found (result will be NULL)
7323 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7324 * error anyway, so let's raise it. */
7325 if (!result)
7326 result = PyErr_SetFromWindowsErr(GetLastError());
7327
7328 CloseHandle(snapshot);
7329
7330 return result;
7331}
7332#endif /*MS_WINDOWS*/
7333
Larry Hastings2f936352014-08-05 14:04:04 +10007334
7335/*[clinic input]
7336os.getppid
7337
7338Return the parent's process id.
7339
7340If the parent process has already exited, Windows machines will still
7341return its id; others systems will return the id of the 'init' process (1).
7342[clinic start generated code]*/
7343
Larry Hastings2f936352014-08-05 14:04:04 +10007344static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007345os_getppid_impl(PyObject *module)
7346/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007347{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007348#ifdef MS_WINDOWS
7349 return win32_getppid();
7350#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007351 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007352#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007353}
7354#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007356
Fred Drake12c6e2d1999-12-14 21:25:03 +00007357#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007358/*[clinic input]
7359os.getlogin
7360
7361Return the actual login name.
7362[clinic start generated code]*/
7363
Larry Hastings2f936352014-08-05 14:04:04 +10007364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007365os_getlogin_impl(PyObject *module)
7366/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007367{
Victor Stinner8c62be82010-05-06 00:08:46 +00007368 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007369#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007370 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007371 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007372
7373 if (GetUserNameW(user_name, &num_chars)) {
7374 /* num_chars is the number of unicode chars plus null terminator */
7375 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007376 }
7377 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007378 result = PyErr_SetFromWindowsErr(GetLastError());
7379#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007380 char *name;
7381 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007382
Victor Stinner8c62be82010-05-06 00:08:46 +00007383 errno = 0;
7384 name = getlogin();
7385 if (name == NULL) {
7386 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007387 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007388 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007389 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007390 }
7391 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007392 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007393 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007394#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007395 return result;
7396}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007397#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007398
Larry Hastings2f936352014-08-05 14:04:04 +10007399
Guido van Rossumad0ee831995-03-01 10:34:45 +00007400#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007401/*[clinic input]
7402os.getuid
7403
7404Return the current process's user id.
7405[clinic start generated code]*/
7406
Larry Hastings2f936352014-08-05 14:04:04 +10007407static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007408os_getuid_impl(PyObject *module)
7409/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007410{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007411 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007412}
Larry Hastings2f936352014-08-05 14:04:04 +10007413#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007414
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007415
Brian Curtineb24d742010-04-12 17:16:38 +00007416#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007417#define HAVE_KILL
7418#endif /* MS_WINDOWS */
7419
7420#ifdef HAVE_KILL
7421/*[clinic input]
7422os.kill
7423
7424 pid: pid_t
7425 signal: Py_ssize_t
7426 /
7427
7428Kill a process with a signal.
7429[clinic start generated code]*/
7430
Larry Hastings2f936352014-08-05 14:04:04 +10007431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007432os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7433/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007434{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007435 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7436 return NULL;
7437 }
7438#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007439 if (kill(pid, (int)signal) == -1)
7440 return posix_error();
7441 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007442#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007443 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007444 DWORD sig = (DWORD)signal;
7445 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007446 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007447
Victor Stinner8c62be82010-05-06 00:08:46 +00007448 /* Console processes which share a common console can be sent CTRL+C or
7449 CTRL+BREAK events, provided they handle said events. */
7450 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007451 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007452 err = GetLastError();
7453 PyErr_SetFromWindowsErr(err);
7454 }
7455 else
7456 Py_RETURN_NONE;
7457 }
Brian Curtineb24d742010-04-12 17:16:38 +00007458
Victor Stinner8c62be82010-05-06 00:08:46 +00007459 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7460 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007461 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007462 if (handle == NULL) {
7463 err = GetLastError();
7464 return PyErr_SetFromWindowsErr(err);
7465 }
Brian Curtineb24d742010-04-12 17:16:38 +00007466
Victor Stinner8c62be82010-05-06 00:08:46 +00007467 if (TerminateProcess(handle, sig) == 0) {
7468 err = GetLastError();
7469 result = PyErr_SetFromWindowsErr(err);
7470 } else {
7471 Py_INCREF(Py_None);
7472 result = Py_None;
7473 }
Brian Curtineb24d742010-04-12 17:16:38 +00007474
Victor Stinner8c62be82010-05-06 00:08:46 +00007475 CloseHandle(handle);
7476 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007477#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007478}
Larry Hastings2f936352014-08-05 14:04:04 +10007479#endif /* HAVE_KILL */
7480
7481
7482#ifdef HAVE_KILLPG
7483/*[clinic input]
7484os.killpg
7485
7486 pgid: pid_t
7487 signal: int
7488 /
7489
7490Kill a process group with a signal.
7491[clinic start generated code]*/
7492
Larry Hastings2f936352014-08-05 14:04:04 +10007493static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007494os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7495/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007496{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007497 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7498 return NULL;
7499 }
Larry Hastings2f936352014-08-05 14:04:04 +10007500 /* XXX some man pages make the `pgid` parameter an int, others
7501 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7502 take the same type. Moreover, pid_t is always at least as wide as
7503 int (else compilation of this module fails), which is safe. */
7504 if (killpg(pgid, signal) == -1)
7505 return posix_error();
7506 Py_RETURN_NONE;
7507}
7508#endif /* HAVE_KILLPG */
7509
Brian Curtineb24d742010-04-12 17:16:38 +00007510
Guido van Rossumc0125471996-06-28 18:55:32 +00007511#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007512#ifdef HAVE_SYS_LOCK_H
7513#include <sys/lock.h>
7514#endif
7515
Larry Hastings2f936352014-08-05 14:04:04 +10007516/*[clinic input]
7517os.plock
7518 op: int
7519 /
7520
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007521Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007522[clinic start generated code]*/
7523
Larry Hastings2f936352014-08-05 14:04:04 +10007524static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007525os_plock_impl(PyObject *module, int op)
7526/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007527{
Victor Stinner8c62be82010-05-06 00:08:46 +00007528 if (plock(op) == -1)
7529 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007530 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007531}
Larry Hastings2f936352014-08-05 14:04:04 +10007532#endif /* HAVE_PLOCK */
7533
Guido van Rossumc0125471996-06-28 18:55:32 +00007534
Guido van Rossumb6775db1994-08-01 11:34:53 +00007535#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007536/*[clinic input]
7537os.setuid
7538
7539 uid: uid_t
7540 /
7541
7542Set the current process's user id.
7543[clinic start generated code]*/
7544
Larry Hastings2f936352014-08-05 14:04:04 +10007545static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007546os_setuid_impl(PyObject *module, uid_t uid)
7547/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007548{
Victor Stinner8c62be82010-05-06 00:08:46 +00007549 if (setuid(uid) < 0)
7550 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007551 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007552}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007553#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007554
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007555
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007556#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007557/*[clinic input]
7558os.seteuid
7559
7560 euid: uid_t
7561 /
7562
7563Set the current process's effective user id.
7564[clinic start generated code]*/
7565
Larry Hastings2f936352014-08-05 14:04:04 +10007566static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007567os_seteuid_impl(PyObject *module, uid_t euid)
7568/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007569{
7570 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007571 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007572 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007573}
7574#endif /* HAVE_SETEUID */
7575
Larry Hastings2f936352014-08-05 14:04:04 +10007576
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007577#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007578/*[clinic input]
7579os.setegid
7580
7581 egid: gid_t
7582 /
7583
7584Set the current process's effective group id.
7585[clinic start generated code]*/
7586
Larry Hastings2f936352014-08-05 14:04:04 +10007587static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007588os_setegid_impl(PyObject *module, gid_t egid)
7589/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007590{
7591 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007592 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007593 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007594}
7595#endif /* HAVE_SETEGID */
7596
Larry Hastings2f936352014-08-05 14:04:04 +10007597
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007598#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007599/*[clinic input]
7600os.setreuid
7601
7602 ruid: uid_t
7603 euid: uid_t
7604 /
7605
7606Set the current process's real and effective user ids.
7607[clinic start generated code]*/
7608
Larry Hastings2f936352014-08-05 14:04:04 +10007609static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007610os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
7611/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007612{
Victor Stinner8c62be82010-05-06 00:08:46 +00007613 if (setreuid(ruid, euid) < 0) {
7614 return posix_error();
7615 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007616 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00007617 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007618}
7619#endif /* HAVE_SETREUID */
7620
Larry Hastings2f936352014-08-05 14:04:04 +10007621
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007622#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10007623/*[clinic input]
7624os.setregid
7625
7626 rgid: gid_t
7627 egid: gid_t
7628 /
7629
7630Set the current process's real and effective group ids.
7631[clinic start generated code]*/
7632
Larry Hastings2f936352014-08-05 14:04:04 +10007633static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007634os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
7635/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007636{
7637 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007639 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007640}
7641#endif /* HAVE_SETREGID */
7642
Larry Hastings2f936352014-08-05 14:04:04 +10007643
Guido van Rossumb6775db1994-08-01 11:34:53 +00007644#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007645/*[clinic input]
7646os.setgid
7647 gid: gid_t
7648 /
7649
7650Set the current process's group id.
7651[clinic start generated code]*/
7652
Larry Hastings2f936352014-08-05 14:04:04 +10007653static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007654os_setgid_impl(PyObject *module, gid_t gid)
7655/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007656{
Victor Stinner8c62be82010-05-06 00:08:46 +00007657 if (setgid(gid) < 0)
7658 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007659 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007660}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007661#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007662
Larry Hastings2f936352014-08-05 14:04:04 +10007663
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007664#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007665/*[clinic input]
7666os.setgroups
7667
7668 groups: object
7669 /
7670
7671Set the groups of the current process to list.
7672[clinic start generated code]*/
7673
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007675os_setgroups(PyObject *module, PyObject *groups)
7676/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007677{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007678 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00007679 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00007680
Victor Stinner8c62be82010-05-06 00:08:46 +00007681 if (!PySequence_Check(groups)) {
7682 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
7683 return NULL;
7684 }
7685 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007686 if (len < 0) {
7687 return NULL;
7688 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 if (len > MAX_GROUPS) {
7690 PyErr_SetString(PyExc_ValueError, "too many groups");
7691 return NULL;
7692 }
7693 for(i = 0; i < len; i++) {
7694 PyObject *elem;
7695 elem = PySequence_GetItem(groups, i);
7696 if (!elem)
7697 return NULL;
7698 if (!PyLong_Check(elem)) {
7699 PyErr_SetString(PyExc_TypeError,
7700 "groups must be integers");
7701 Py_DECREF(elem);
7702 return NULL;
7703 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007704 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 Py_DECREF(elem);
7706 return NULL;
7707 }
7708 }
7709 Py_DECREF(elem);
7710 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007711
Victor Stinner8c62be82010-05-06 00:08:46 +00007712 if (setgroups(len, grouplist) < 0)
7713 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007714 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007715}
7716#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007717
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007718#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
7719static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02007720wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007721{
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08007723 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007724
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 if (pid == -1)
7726 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007727
Zackery Spytz682107c2019-09-09 09:48:32 -06007728 // If wait succeeded but no child was ready to report status, ru will not
7729 // have been populated.
7730 if (pid == 0) {
7731 memset(ru, 0, sizeof(*ru));
7732 }
7733
Eddie Elizondob3966632019-11-05 07:16:14 -08007734 PyObject *m = PyImport_ImportModuleNoBlock("resource");
7735 if (m == NULL)
7736 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02007737 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08007738 Py_DECREF(m);
7739 if (struct_rusage == NULL)
7740 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007741
Victor Stinner8c62be82010-05-06 00:08:46 +00007742 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
7743 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08007744 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 if (!result)
7746 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007747
7748#ifndef doubletime
7749#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
7750#endif
7751
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007753 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007755 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007756#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00007757 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
7758 SET_INT(result, 2, ru->ru_maxrss);
7759 SET_INT(result, 3, ru->ru_ixrss);
7760 SET_INT(result, 4, ru->ru_idrss);
7761 SET_INT(result, 5, ru->ru_isrss);
7762 SET_INT(result, 6, ru->ru_minflt);
7763 SET_INT(result, 7, ru->ru_majflt);
7764 SET_INT(result, 8, ru->ru_nswap);
7765 SET_INT(result, 9, ru->ru_inblock);
7766 SET_INT(result, 10, ru->ru_oublock);
7767 SET_INT(result, 11, ru->ru_msgsnd);
7768 SET_INT(result, 12, ru->ru_msgrcv);
7769 SET_INT(result, 13, ru->ru_nsignals);
7770 SET_INT(result, 14, ru->ru_nvcsw);
7771 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007772#undef SET_INT
7773
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 if (PyErr_Occurred()) {
7775 Py_DECREF(result);
7776 return NULL;
7777 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007778
Victor Stinner8c62be82010-05-06 00:08:46 +00007779 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007780}
7781#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7782
Larry Hastings2f936352014-08-05 14:04:04 +10007783
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007784#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10007785/*[clinic input]
7786os.wait3
7787
7788 options: int
7789Wait for completion of a child process.
7790
7791Returns a tuple of information about the child process:
7792 (pid, status, rusage)
7793[clinic start generated code]*/
7794
Larry Hastings2f936352014-08-05 14:04:04 +10007795static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007796os_wait3_impl(PyObject *module, int options)
7797/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007798{
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007801 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 WAIT_TYPE status;
7803 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007804
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007805 do {
7806 Py_BEGIN_ALLOW_THREADS
7807 pid = wait3(&status, options, &ru);
7808 Py_END_ALLOW_THREADS
7809 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7810 if (pid < 0)
7811 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007812
Victor Stinner1c2fa782020-05-10 11:05:29 +02007813 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007814}
7815#endif /* HAVE_WAIT3 */
7816
Larry Hastings2f936352014-08-05 14:04:04 +10007817
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007818#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10007819/*[clinic input]
7820
7821os.wait4
7822
7823 pid: pid_t
7824 options: int
7825
7826Wait for completion of a specific child process.
7827
7828Returns a tuple of information about the child process:
7829 (pid, status, rusage)
7830[clinic start generated code]*/
7831
Larry Hastings2f936352014-08-05 14:04:04 +10007832static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007833os_wait4_impl(PyObject *module, pid_t pid, int options)
7834/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007835{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007836 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007837 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007838 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 WAIT_TYPE status;
7840 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007841
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007842 do {
7843 Py_BEGIN_ALLOW_THREADS
7844 res = wait4(pid, &status, options, &ru);
7845 Py_END_ALLOW_THREADS
7846 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7847 if (res < 0)
7848 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007849
Victor Stinner1c2fa782020-05-10 11:05:29 +02007850 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007851}
7852#endif /* HAVE_WAIT4 */
7853
Larry Hastings2f936352014-08-05 14:04:04 +10007854
Ross Lagerwall7807c352011-03-17 20:20:30 +02007855#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10007856/*[clinic input]
7857os.waitid
7858
7859 idtype: idtype_t
7860 Must be one of be P_PID, P_PGID or P_ALL.
7861 id: id_t
7862 The id to wait on.
7863 options: int
7864 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7865 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7866 /
7867
7868Returns the result of waiting for a process or processes.
7869
7870Returns either waitid_result or None if WNOHANG is specified and there are
7871no children in a waitable state.
7872[clinic start generated code]*/
7873
Larry Hastings2f936352014-08-05 14:04:04 +10007874static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007875os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7876/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007877{
7878 PyObject *result;
7879 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007880 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007881 siginfo_t si;
7882 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007883
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007884 do {
7885 Py_BEGIN_ALLOW_THREADS
7886 res = waitid(idtype, id, &si, options);
7887 Py_END_ALLOW_THREADS
7888 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7889 if (res < 0)
7890 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007891
7892 if (si.si_pid == 0)
7893 Py_RETURN_NONE;
7894
Hai Shif707d942020-03-16 21:15:01 +08007895 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08007896 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007897 if (!result)
7898 return NULL;
7899
7900 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007901 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007902 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7903 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7904 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7905 if (PyErr_Occurred()) {
7906 Py_DECREF(result);
7907 return NULL;
7908 }
7909
7910 return result;
7911}
Larry Hastings2f936352014-08-05 14:04:04 +10007912#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007913
Larry Hastings2f936352014-08-05 14:04:04 +10007914
7915#if defined(HAVE_WAITPID)
7916/*[clinic input]
7917os.waitpid
7918 pid: pid_t
7919 options: int
7920 /
7921
7922Wait for completion of a given child process.
7923
7924Returns a tuple of information regarding the child process:
7925 (pid, status)
7926
7927The options argument is ignored on Windows.
7928[clinic start generated code]*/
7929
Larry Hastings2f936352014-08-05 14:04:04 +10007930static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007931os_waitpid_impl(PyObject *module, pid_t pid, int options)
7932/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007933{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007934 pid_t res;
7935 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 WAIT_TYPE status;
7937 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007938
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007939 do {
7940 Py_BEGIN_ALLOW_THREADS
7941 res = waitpid(pid, &status, options);
7942 Py_END_ALLOW_THREADS
7943 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7944 if (res < 0)
7945 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007946
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007947 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007948}
Tim Petersab034fa2002-02-01 11:27:43 +00007949#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007950/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007951/*[clinic input]
7952os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007953 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007954 options: int
7955 /
7956
7957Wait for completion of a given process.
7958
7959Returns a tuple of information regarding the process:
7960 (pid, status << 8)
7961
7962The options argument is ignored on Windows.
7963[clinic start generated code]*/
7964
Larry Hastings2f936352014-08-05 14:04:04 +10007965static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007966os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007967/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007968{
7969 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007970 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007971 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007972
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007973 do {
7974 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007975 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007976 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007977 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007978 Py_END_ALLOW_THREADS
7979 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007980 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007981 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007982
Victor Stinner9bee32b2020-04-22 16:30:35 +02007983 unsigned long long ustatus = (unsigned int)status;
7984
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02007986 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007987}
Larry Hastings2f936352014-08-05 14:04:04 +10007988#endif
7989
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007990
Guido van Rossumad0ee831995-03-01 10:34:45 +00007991#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007992/*[clinic input]
7993os.wait
7994
7995Wait for completion of a child process.
7996
7997Returns a tuple of information about the child process:
7998 (pid, status)
7999[clinic start generated code]*/
8000
Larry Hastings2f936352014-08-05 14:04:04 +10008001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008002os_wait_impl(PyObject *module)
8003/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008004{
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008006 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 WAIT_TYPE status;
8008 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008009
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008010 do {
8011 Py_BEGIN_ALLOW_THREADS
8012 pid = wait(&status);
8013 Py_END_ALLOW_THREADS
8014 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8015 if (pid < 0)
8016 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008017
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008019}
Larry Hastings2f936352014-08-05 14:04:04 +10008020#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008021
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008022#if defined(__linux__) && defined(__NR_pidfd_open)
8023/*[clinic input]
8024os.pidfd_open
8025 pid: pid_t
8026 flags: unsigned_int = 0
8027
8028Return a file descriptor referring to the process *pid*.
8029
8030The descriptor can be used to perform process management without races and
8031signals.
8032[clinic start generated code]*/
8033
8034static PyObject *
8035os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8036/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8037{
8038 int fd = syscall(__NR_pidfd_open, pid, flags);
8039 if (fd < 0) {
8040 return posix_error();
8041 }
8042 return PyLong_FromLong(fd);
8043}
8044#endif
8045
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008046
Larry Hastings9cf065c2012-06-22 16:30:09 -07008047#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008048/*[clinic input]
8049os.readlink
8050
8051 path: path_t
8052 *
8053 dir_fd: dir_fd(requires='readlinkat') = None
8054
8055Return a string representing the path to which the symbolic link points.
8056
8057If dir_fd is not None, it should be a file descriptor open to a directory,
8058and path should be relative; path will then be relative to that directory.
8059
8060dir_fd may not be implemented on your platform. If it is unavailable,
8061using it will raise a NotImplementedError.
8062[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008063
Barry Warsaw53699e91996-12-10 23:23:01 +00008064static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008065os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8066/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008067{
Berker Peksage0b5b202018-08-15 13:03:41 +03008068#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008069 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008070 ssize_t length;
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008071
8072 Py_BEGIN_ALLOW_THREADS
8073#ifdef HAVE_READLINKAT
8074 if (dir_fd != DEFAULT_DIR_FD)
8075 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8076 else
8077#endif
8078 length = readlink(path->narrow, buffer, MAXPATHLEN);
8079 Py_END_ALLOW_THREADS
8080
8081 if (length < 0) {
8082 return path_error(path);
8083 }
8084 buffer[length] = '\0';
8085
8086 if (PyUnicode_Check(path->object))
8087 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8088 else
8089 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008090#elif defined(MS_WINDOWS)
8091 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008092 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008093 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008094 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8095 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008096 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008097
Larry Hastings2f936352014-08-05 14:04:04 +10008098 /* First get a handle to the reparse point */
8099 Py_BEGIN_ALLOW_THREADS
8100 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008101 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008102 0,
8103 0,
8104 0,
8105 OPEN_EXISTING,
8106 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8107 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008108 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8109 /* New call DeviceIoControl to read the reparse point */
8110 io_result = DeviceIoControl(
8111 reparse_point_handle,
8112 FSCTL_GET_REPARSE_POINT,
8113 0, 0, /* in buffer */
8114 target_buffer, sizeof(target_buffer),
8115 &n_bytes_returned,
8116 0 /* we're not using OVERLAPPED_IO */
8117 );
8118 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008119 }
Larry Hastings2f936352014-08-05 14:04:04 +10008120 Py_END_ALLOW_THREADS
8121
Berker Peksage0b5b202018-08-15 13:03:41 +03008122 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008123 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008124 }
Larry Hastings2f936352014-08-05 14:04:04 +10008125
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008126 wchar_t *name = NULL;
8127 Py_ssize_t nameLen = 0;
8128 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008129 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008130 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8131 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8132 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008133 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008134 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8135 {
8136 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8137 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8138 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8139 }
8140 else
8141 {
8142 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8143 }
8144 if (name) {
8145 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8146 /* Our buffer is mutable, so this is okay */
8147 name[1] = L'\\';
8148 }
8149 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008150 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008151 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8152 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008153 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008154 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008155#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008156}
Berker Peksage0b5b202018-08-15 13:03:41 +03008157#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008158
Larry Hastings9cf065c2012-06-22 16:30:09 -07008159#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
Minmin Gong7f21c9a2020-05-18 09:17:19 -07008181#endif
8182
8183#ifdef HAVE_SYMLINK
8184
8185#if defined(MS_WINDOWS)
8186
Victor Stinner31b3b922013-06-05 01:49:17 +02008187/* Is this path absolute? */
8188static int
8189_is_absW(const WCHAR *path)
8190{
Steve Dower6921e732018-03-05 14:26:08 -08008191 return path[0] == L'\\' || path[0] == L'/' ||
8192 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008193}
8194
Steve Dower6921e732018-03-05 14:26:08 -08008195/* join root and rest with a backslash - return 0 on success */
8196static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008197_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8198{
Victor Stinner31b3b922013-06-05 01:49:17 +02008199 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008200 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008201 }
8202
Steve Dower6921e732018-03-05 14:26:08 -08008203 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8204 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008205 }
Steve Dower6921e732018-03-05 14:26:08 -08008206
8207 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8208 return -1;
8209 }
8210
8211 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008212}
8213
Victor Stinner31b3b922013-06-05 01:49:17 +02008214/* Return True if the path at src relative to dest is a directory */
8215static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008216_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008217{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008218 WIN32_FILE_ATTRIBUTE_DATA src_info;
8219 WCHAR dest_parent[MAX_PATH];
8220 WCHAR src_resolved[MAX_PATH] = L"";
8221
8222 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008223 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8224 _dirnameW(dest_parent)) {
8225 return 0;
8226 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008227 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008228 if (_joinW(src_resolved, dest_parent, src)) {
8229 return 0;
8230 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008231 return (
8232 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8233 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8234 );
8235}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008236#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008237
Larry Hastings2f936352014-08-05 14:04:04 +10008238
8239/*[clinic input]
8240os.symlink
8241 src: path_t
8242 dst: path_t
8243 target_is_directory: bool = False
8244 *
8245 dir_fd: dir_fd(requires='symlinkat')=None
8246
8247# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8248
8249Create a symbolic link pointing to src named dst.
8250
8251target_is_directory is required on Windows if the target is to be
8252 interpreted as a directory. (On Windows, symlink requires
8253 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8254 target_is_directory is ignored on non-Windows platforms.
8255
8256If dir_fd is not None, it should be a file descriptor open to a directory,
8257 and path should be relative; path will then be relative to that directory.
8258dir_fd may not be implemented on your platform.
8259 If it is unavailable, using it will raise a NotImplementedError.
8260
8261[clinic start generated code]*/
8262
Larry Hastings2f936352014-08-05 14:04:04 +10008263static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008264os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008265 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008266/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008267{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008268#ifdef MS_WINDOWS
8269 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008270 DWORD flags = 0;
8271
8272 /* Assumed true, set to false if detected to not be available. */
8273 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008274#else
8275 int result;
8276#endif
8277
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008278 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8279 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8280 return NULL;
8281 }
8282
Larry Hastings9cf065c2012-06-22 16:30:09 -07008283#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008284
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008285 if (windows_has_symlink_unprivileged_flag) {
8286 /* Allow non-admin symlinks if system allows it. */
8287 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8288 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008289
Larry Hastings9cf065c2012-06-22 16:30:09 -07008290 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008291 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008292 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8293 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8294 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8295 }
8296
8297 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008298 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008299 Py_END_ALLOW_THREADS
8300
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008301 if (windows_has_symlink_unprivileged_flag && !result &&
8302 ERROR_INVALID_PARAMETER == GetLastError()) {
8303
8304 Py_BEGIN_ALLOW_THREADS
8305 _Py_BEGIN_SUPPRESS_IPH
8306 /* This error might be caused by
8307 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8308 Try again, and update windows_has_symlink_unprivileged_flag if we
8309 are successful this time.
8310
8311 NOTE: There is a risk of a race condition here if there are other
8312 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8313 another process (or thread) changes that condition in between our
8314 calls to CreateSymbolicLink.
8315 */
8316 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8317 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8318 _Py_END_SUPPRESS_IPH
8319 Py_END_ALLOW_THREADS
8320
8321 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8322 windows_has_symlink_unprivileged_flag = FALSE;
8323 }
8324 }
8325
Larry Hastings2f936352014-08-05 14:04:04 +10008326 if (!result)
8327 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008328
8329#else
8330
Steve Dower6921e732018-03-05 14:26:08 -08008331 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8332 PyErr_SetString(PyExc_ValueError,
8333 "symlink: src and dst must be the same type");
8334 return NULL;
8335 }
8336
Larry Hastings9cf065c2012-06-22 16:30:09 -07008337 Py_BEGIN_ALLOW_THREADS
8338#if HAVE_SYMLINKAT
8339 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10008340 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008341 else
8342#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008343 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008344 Py_END_ALLOW_THREADS
8345
Larry Hastings2f936352014-08-05 14:04:04 +10008346 if (result)
8347 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008348#endif
8349
Larry Hastings2f936352014-08-05 14:04:04 +10008350 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008351}
8352#endif /* HAVE_SYMLINK */
8353
Larry Hastings9cf065c2012-06-22 16:30:09 -07008354
Brian Curtind40e6f72010-07-08 21:39:08 +00008355
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008356
Larry Hastings605a62d2012-06-24 04:33:36 -07008357static PyStructSequence_Field times_result_fields[] = {
8358 {"user", "user time"},
8359 {"system", "system time"},
8360 {"children_user", "user time of children"},
8361 {"children_system", "system time of children"},
8362 {"elapsed", "elapsed time since an arbitrary point in the past"},
8363 {NULL}
8364};
8365
8366PyDoc_STRVAR(times_result__doc__,
8367"times_result: Result from os.times().\n\n\
8368This object may be accessed either as a tuple of\n\
8369 (user, system, children_user, children_system, elapsed),\n\
8370or via the attributes user, system, children_user, children_system,\n\
8371and elapsed.\n\
8372\n\
8373See os.times for more information.");
8374
8375static PyStructSequence_Desc times_result_desc = {
8376 "times_result", /* name */
8377 times_result__doc__, /* doc */
8378 times_result_fields,
8379 5
8380};
8381
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008382#ifdef MS_WINDOWS
8383#define HAVE_TIMES /* mandatory, for the method table */
8384#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008385
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008386#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008387
8388static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008389build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008390 double children_user, double children_system,
8391 double elapsed)
8392{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008393 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008394 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008395 if (value == NULL)
8396 return NULL;
8397
8398#define SET(i, field) \
8399 { \
8400 PyObject *o = PyFloat_FromDouble(field); \
8401 if (!o) { \
8402 Py_DECREF(value); \
8403 return NULL; \
8404 } \
8405 PyStructSequence_SET_ITEM(value, i, o); \
8406 } \
8407
8408 SET(0, user);
8409 SET(1, system);
8410 SET(2, children_user);
8411 SET(3, children_system);
8412 SET(4, elapsed);
8413
8414#undef SET
8415
8416 return value;
8417}
8418
Larry Hastings605a62d2012-06-24 04:33:36 -07008419
Larry Hastings2f936352014-08-05 14:04:04 +10008420#ifndef MS_WINDOWS
8421#define NEED_TICKS_PER_SECOND
8422static long ticks_per_second = -1;
8423#endif /* MS_WINDOWS */
8424
8425/*[clinic input]
8426os.times
8427
8428Return a collection containing process timing information.
8429
8430The object returned behaves like a named tuple with these fields:
8431 (utime, stime, cutime, cstime, elapsed_time)
8432All fields are floating point numbers.
8433[clinic start generated code]*/
8434
Larry Hastings2f936352014-08-05 14:04:04 +10008435static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008436os_times_impl(PyObject *module)
8437/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008438#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008439{
Victor Stinner8c62be82010-05-06 00:08:46 +00008440 FILETIME create, exit, kernel, user;
8441 HANDLE hProc;
8442 hProc = GetCurrentProcess();
8443 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8444 /* The fields of a FILETIME structure are the hi and lo part
8445 of a 64-bit value expressed in 100 nanosecond units.
8446 1e7 is one second in such units; 1e-7 the inverse.
8447 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8448 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008449 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008450 (double)(user.dwHighDateTime*429.4967296 +
8451 user.dwLowDateTime*1e-7),
8452 (double)(kernel.dwHighDateTime*429.4967296 +
8453 kernel.dwLowDateTime*1e-7),
8454 (double)0,
8455 (double)0,
8456 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008457}
Larry Hastings2f936352014-08-05 14:04:04 +10008458#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008459{
Larry Hastings2f936352014-08-05 14:04:04 +10008460
8461
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008462 struct tms t;
8463 clock_t c;
8464 errno = 0;
8465 c = times(&t);
8466 if (c == (clock_t) -1)
8467 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008468 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008469 (double)t.tms_utime / ticks_per_second,
8470 (double)t.tms_stime / ticks_per_second,
8471 (double)t.tms_cutime / ticks_per_second,
8472 (double)t.tms_cstime / ticks_per_second,
8473 (double)c / ticks_per_second);
8474}
Larry Hastings2f936352014-08-05 14:04:04 +10008475#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008476#endif /* HAVE_TIMES */
8477
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008478
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008479#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008480/*[clinic input]
8481os.getsid
8482
8483 pid: pid_t
8484 /
8485
8486Call the system call getsid(pid) and return the result.
8487[clinic start generated code]*/
8488
Larry Hastings2f936352014-08-05 14:04:04 +10008489static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008490os_getsid_impl(PyObject *module, pid_t pid)
8491/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008492{
Victor Stinner8c62be82010-05-06 00:08:46 +00008493 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008494 sid = getsid(pid);
8495 if (sid < 0)
8496 return posix_error();
8497 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008498}
8499#endif /* HAVE_GETSID */
8500
8501
Guido van Rossumb6775db1994-08-01 11:34:53 +00008502#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008503/*[clinic input]
8504os.setsid
8505
8506Call the system call setsid().
8507[clinic start generated code]*/
8508
Larry Hastings2f936352014-08-05 14:04:04 +10008509static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008510os_setsid_impl(PyObject *module)
8511/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008512{
Victor Stinner8c62be82010-05-06 00:08:46 +00008513 if (setsid() < 0)
8514 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008515 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008516}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008517#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008518
Larry Hastings2f936352014-08-05 14:04:04 +10008519
Guido van Rossumb6775db1994-08-01 11:34:53 +00008520#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008521/*[clinic input]
8522os.setpgid
8523
8524 pid: pid_t
8525 pgrp: pid_t
8526 /
8527
8528Call the system call setpgid(pid, pgrp).
8529[clinic start generated code]*/
8530
Larry Hastings2f936352014-08-05 14:04:04 +10008531static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008532os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8533/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008534{
Victor Stinner8c62be82010-05-06 00:08:46 +00008535 if (setpgid(pid, pgrp) < 0)
8536 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008537 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008538}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008539#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008540
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008541
Guido van Rossumb6775db1994-08-01 11:34:53 +00008542#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008543/*[clinic input]
8544os.tcgetpgrp
8545
8546 fd: int
8547 /
8548
8549Return the process group associated with the terminal specified by fd.
8550[clinic start generated code]*/
8551
Larry Hastings2f936352014-08-05 14:04:04 +10008552static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008553os_tcgetpgrp_impl(PyObject *module, int fd)
8554/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008555{
8556 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008557 if (pgid < 0)
8558 return posix_error();
8559 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008560}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008561#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008562
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008563
Guido van Rossumb6775db1994-08-01 11:34:53 +00008564#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008565/*[clinic input]
8566os.tcsetpgrp
8567
8568 fd: int
8569 pgid: pid_t
8570 /
8571
8572Set the process group associated with the terminal specified by fd.
8573[clinic start generated code]*/
8574
Larry Hastings2f936352014-08-05 14:04:04 +10008575static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008576os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8577/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008578{
Victor Stinner8c62be82010-05-06 00:08:46 +00008579 if (tcsetpgrp(fd, pgid) < 0)
8580 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008581 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00008582}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008583#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00008584
Guido van Rossum687dd131993-05-17 08:34:16 +00008585/* Functions acting on file descriptors */
8586
Victor Stinnerdaf45552013-08-28 00:53:59 +02008587#ifdef O_CLOEXEC
8588extern int _Py_open_cloexec_works;
8589#endif
8590
Larry Hastings2f936352014-08-05 14:04:04 +10008591
8592/*[clinic input]
8593os.open -> int
8594 path: path_t
8595 flags: int
8596 mode: int = 0o777
8597 *
8598 dir_fd: dir_fd(requires='openat') = None
8599
8600# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
8601
8602Open a file for low level IO. Returns a file descriptor (integer).
8603
8604If dir_fd is not None, it should be a file descriptor open to a directory,
8605 and path should be relative; path will then be relative to that directory.
8606dir_fd may not be implemented on your platform.
8607 If it is unavailable, using it will raise a NotImplementedError.
8608[clinic start generated code]*/
8609
Larry Hastings2f936352014-08-05 14:04:04 +10008610static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008611os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
8612/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008613{
8614 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008615 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008616
Victor Stinnerdaf45552013-08-28 00:53:59 +02008617#ifdef O_CLOEXEC
8618 int *atomic_flag_works = &_Py_open_cloexec_works;
8619#elif !defined(MS_WINDOWS)
8620 int *atomic_flag_works = NULL;
8621#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00008622
Victor Stinnerdaf45552013-08-28 00:53:59 +02008623#ifdef MS_WINDOWS
8624 flags |= O_NOINHERIT;
8625#elif defined(O_CLOEXEC)
8626 flags |= O_CLOEXEC;
8627#endif
8628
Steve Dowerb82e17e2019-05-23 08:45:22 -07008629 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
8630 return -1;
8631 }
8632
Steve Dower8fc89802015-04-12 00:26:27 -04008633 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008634 do {
8635 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008636#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008637 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008638#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008639#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008640 if (dir_fd != DEFAULT_DIR_FD)
8641 fd = openat(dir_fd, path->narrow, flags, mode);
8642 else
Steve Dower6230aaf2016-09-09 09:03:15 -07008643#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008644 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07008645#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008646 Py_END_ALLOW_THREADS
8647 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008648 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00008649
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008650 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008651 if (!async_err)
8652 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10008653 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008654 }
8655
Victor Stinnerdaf45552013-08-28 00:53:59 +02008656#ifndef MS_WINDOWS
8657 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
8658 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10008659 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008660 }
8661#endif
8662
Larry Hastings2f936352014-08-05 14:04:04 +10008663 return fd;
8664}
8665
8666
8667/*[clinic input]
8668os.close
8669
8670 fd: int
8671
8672Close a file descriptor.
8673[clinic start generated code]*/
8674
Barry Warsaw53699e91996-12-10 23:23:01 +00008675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008676os_close_impl(PyObject *module, int fd)
8677/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008678{
Larry Hastings2f936352014-08-05 14:04:04 +10008679 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008680 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
8681 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
8682 * for more details.
8683 */
Victor Stinner8c62be82010-05-06 00:08:46 +00008684 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008685 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008686 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04008687 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 Py_END_ALLOW_THREADS
8689 if (res < 0)
8690 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008691 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008692}
8693
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008694
Jakub Kulíke20134f2019-09-11 17:11:57 +02008695#ifdef HAVE_FDWALK
8696static int
8697_fdwalk_close_func(void *lohi, int fd)
8698{
8699 int lo = ((int *)lohi)[0];
8700 int hi = ((int *)lohi)[1];
8701
Victor Stinner162c5672020-04-24 12:00:51 +02008702 if (fd >= hi) {
Jakub Kulíke20134f2019-09-11 17:11:57 +02008703 return 1;
Victor Stinner162c5672020-04-24 12:00:51 +02008704 }
8705 else if (fd >= lo) {
8706 /* Ignore errors */
8707 (void)close(fd);
8708 }
Jakub Kulíke20134f2019-09-11 17:11:57 +02008709 return 0;
8710}
8711#endif /* HAVE_FDWALK */
8712
Larry Hastings2f936352014-08-05 14:04:04 +10008713/*[clinic input]
8714os.closerange
8715
8716 fd_low: int
8717 fd_high: int
8718 /
8719
8720Closes all file descriptors in [fd_low, fd_high), ignoring errors.
8721[clinic start generated code]*/
8722
Larry Hastings2f936352014-08-05 14:04:04 +10008723static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008724os_closerange_impl(PyObject *module, int fd_low, int fd_high)
8725/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008726{
Jakub Kulíke20134f2019-09-11 17:11:57 +02008727#ifdef HAVE_FDWALK
8728 int lohi[2];
Jakub Kulíke20134f2019-09-11 17:11:57 +02008729#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008730 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008731 _Py_BEGIN_SUPPRESS_IPH
Jakub Kulíke20134f2019-09-11 17:11:57 +02008732#ifdef HAVE_FDWALK
8733 lohi[0] = Py_MAX(fd_low, 0);
8734 lohi[1] = fd_high;
8735 fdwalk(_fdwalk_close_func, lohi);
8736#else
Victor Stinner162c5672020-04-24 12:00:51 +02008737 fd_low = Py_MAX(fd_low, 0);
8738#ifdef __FreeBSD__
8739 if (fd_high >= sysconf(_SC_OPEN_MAX)) {
8740 /* Any errors encountered while closing file descriptors are ignored */
8741 closefrom(fd_low);
8742 }
8743 else
8744#endif
8745 {
8746 for (int i = fd_low; i < fd_high; i++) {
8747 /* Ignore errors */
8748 (void)close(i);
8749 }
8750 }
Jakub Kulíke20134f2019-09-11 17:11:57 +02008751#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008752 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008753 Py_END_ALLOW_THREADS
8754 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00008755}
8756
8757
Larry Hastings2f936352014-08-05 14:04:04 +10008758/*[clinic input]
8759os.dup -> int
8760
8761 fd: int
8762 /
8763
8764Return a duplicate of a file descriptor.
8765[clinic start generated code]*/
8766
Larry Hastings2f936352014-08-05 14:04:04 +10008767static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008768os_dup_impl(PyObject *module, int fd)
8769/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008770{
8771 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00008772}
8773
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008774
Larry Hastings2f936352014-08-05 14:04:04 +10008775/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008776os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10008777 fd: int
8778 fd2: int
8779 inheritable: bool=True
8780
8781Duplicate file descriptor.
8782[clinic start generated code]*/
8783
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008784static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008785os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008786/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008787{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01008788 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008789#if defined(HAVE_DUP3) && \
8790 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
8791 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03008792 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008793#endif
8794
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008795 if (fd < 0 || fd2 < 0) {
8796 posix_error();
8797 return -1;
8798 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008799
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008800 /* dup2() can fail with EINTR if the target FD is already open, because it
8801 * then has to be closed. See os_close_impl() for why we don't handle EINTR
8802 * upon close(), and therefore below.
8803 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02008804#ifdef MS_WINDOWS
8805 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008806 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008807 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04008808 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008809 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008810 if (res < 0) {
8811 posix_error();
8812 return -1;
8813 }
8814 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02008815
8816 /* Character files like console cannot be make non-inheritable */
8817 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8818 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008819 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008820 }
8821
8822#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
8823 Py_BEGIN_ALLOW_THREADS
8824 if (!inheritable)
8825 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
8826 else
8827 res = dup2(fd, fd2);
8828 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008829 if (res < 0) {
8830 posix_error();
8831 return -1;
8832 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008833
8834#else
8835
8836#ifdef HAVE_DUP3
8837 if (!inheritable && dup3_works != 0) {
8838 Py_BEGIN_ALLOW_THREADS
8839 res = dup3(fd, fd2, O_CLOEXEC);
8840 Py_END_ALLOW_THREADS
8841 if (res < 0) {
8842 if (dup3_works == -1)
8843 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008844 if (dup3_works) {
8845 posix_error();
8846 return -1;
8847 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008848 }
8849 }
8850
8851 if (inheritable || dup3_works == 0)
8852 {
8853#endif
8854 Py_BEGIN_ALLOW_THREADS
8855 res = dup2(fd, fd2);
8856 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008857 if (res < 0) {
8858 posix_error();
8859 return -1;
8860 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02008861
8862 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
8863 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008864 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008865 }
8866#ifdef HAVE_DUP3
8867 }
8868#endif
8869
8870#endif
8871
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08008872 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00008873}
8874
Larry Hastings2f936352014-08-05 14:04:04 +10008875
Ross Lagerwall7807c352011-03-17 20:20:30 +02008876#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008877/*[clinic input]
8878os.lockf
8879
8880 fd: int
8881 An open file descriptor.
8882 command: int
8883 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8884 length: Py_off_t
8885 The number of bytes to lock, starting at the current position.
8886 /
8887
8888Apply, test or remove a POSIX lock on an open file descriptor.
8889
8890[clinic start generated code]*/
8891
Larry Hastings2f936352014-08-05 14:04:04 +10008892static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008893os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8894/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008895{
8896 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008897
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008898 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
8899 return NULL;
8900 }
8901
Ross Lagerwall7807c352011-03-17 20:20:30 +02008902 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008903 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008904 Py_END_ALLOW_THREADS
8905
8906 if (res < 0)
8907 return posix_error();
8908
8909 Py_RETURN_NONE;
8910}
Larry Hastings2f936352014-08-05 14:04:04 +10008911#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008912
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008913
Larry Hastings2f936352014-08-05 14:04:04 +10008914/*[clinic input]
8915os.lseek -> Py_off_t
8916
8917 fd: int
8918 position: Py_off_t
8919 how: int
8920 /
8921
8922Set the position of a file descriptor. Return the new position.
8923
8924Return the new cursor position in number of bytes
8925relative to the beginning of the file.
8926[clinic start generated code]*/
8927
Larry Hastings2f936352014-08-05 14:04:04 +10008928static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008929os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8930/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008931{
8932 Py_off_t result;
8933
Guido van Rossum687dd131993-05-17 08:34:16 +00008934#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8936 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008937 case 0: how = SEEK_SET; break;
8938 case 1: how = SEEK_CUR; break;
8939 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008941#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008942
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008944 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008945#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008946 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008947#else
Larry Hastings2f936352014-08-05 14:04:04 +10008948 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008949#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008950 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008952 if (result < 0)
8953 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008954
Larry Hastings2f936352014-08-05 14:04:04 +10008955 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008956}
8957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008958
Larry Hastings2f936352014-08-05 14:04:04 +10008959/*[clinic input]
8960os.read
8961 fd: int
8962 length: Py_ssize_t
8963 /
8964
8965Read from a file descriptor. Returns a bytes object.
8966[clinic start generated code]*/
8967
Larry Hastings2f936352014-08-05 14:04:04 +10008968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008969os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8970/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008971{
Victor Stinner8c62be82010-05-06 00:08:46 +00008972 Py_ssize_t n;
8973 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008974
8975 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 errno = EINVAL;
8977 return posix_error();
8978 }
Larry Hastings2f936352014-08-05 14:04:04 +10008979
Victor Stinner9a0d7a72018-11-22 15:03:40 +01008980 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008981
8982 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008983 if (buffer == NULL)
8984 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008985
Victor Stinner66aab0c2015-03-19 22:53:20 +01008986 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8987 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008988 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008989 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008990 }
Larry Hastings2f936352014-08-05 14:04:04 +10008991
8992 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008993 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008994
Victor Stinner8c62be82010-05-06 00:08:46 +00008995 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008996}
8997
Ross Lagerwall7807c352011-03-17 20:20:30 +02008998#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03008999 || defined(__APPLE__))) \
9000 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9001 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9002static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009003iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009004{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009005 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009006
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009007 *iov = PyMem_New(struct iovec, cnt);
9008 if (*iov == NULL) {
9009 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009010 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009011 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009012
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009013 *buf = PyMem_New(Py_buffer, cnt);
9014 if (*buf == NULL) {
9015 PyMem_Del(*iov);
9016 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009017 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009018 }
9019
9020 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009021 PyObject *item = PySequence_GetItem(seq, i);
9022 if (item == NULL)
9023 goto fail;
9024 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9025 Py_DECREF(item);
9026 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009027 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009028 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009029 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009030 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009031 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009032 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009033
9034fail:
9035 PyMem_Del(*iov);
9036 for (j = 0; j < i; j++) {
9037 PyBuffer_Release(&(*buf)[j]);
9038 }
9039 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009040 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009041}
9042
9043static void
9044iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9045{
9046 int i;
9047 PyMem_Del(iov);
9048 for (i = 0; i < cnt; i++) {
9049 PyBuffer_Release(&buf[i]);
9050 }
9051 PyMem_Del(buf);
9052}
9053#endif
9054
Larry Hastings2f936352014-08-05 14:04:04 +10009055
Ross Lagerwall7807c352011-03-17 20:20:30 +02009056#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009057/*[clinic input]
9058os.readv -> Py_ssize_t
9059
9060 fd: int
9061 buffers: object
9062 /
9063
9064Read from a file descriptor fd into an iterable of buffers.
9065
9066The buffers should be mutable buffers accepting bytes.
9067readv will transfer data into each buffer until it is full
9068and then move on to the next buffer in the sequence to hold
9069the rest of the data.
9070
9071readv returns the total number of bytes read,
9072which may be less than the total capacity of all the buffers.
9073[clinic start generated code]*/
9074
Larry Hastings2f936352014-08-05 14:04:04 +10009075static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009076os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9077/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009078{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009079 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009080 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009081 struct iovec *iov;
9082 Py_buffer *buf;
9083
Larry Hastings2f936352014-08-05 14:04:04 +10009084 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009085 PyErr_SetString(PyExc_TypeError,
9086 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009087 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009088 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009089
Larry Hastings2f936352014-08-05 14:04:04 +10009090 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009091 if (cnt < 0)
9092 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009093
9094 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9095 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009096
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009097 do {
9098 Py_BEGIN_ALLOW_THREADS
9099 n = readv(fd, iov, cnt);
9100 Py_END_ALLOW_THREADS
9101 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009102
9103 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009104 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009105 if (!async_err)
9106 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009107 return -1;
9108 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009109
Larry Hastings2f936352014-08-05 14:04:04 +10009110 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009111}
Larry Hastings2f936352014-08-05 14:04:04 +10009112#endif /* HAVE_READV */
9113
Ross Lagerwall7807c352011-03-17 20:20:30 +02009114
9115#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009116/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009117os.pread
9118
9119 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009120 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009121 offset: Py_off_t
9122 /
9123
9124Read a number of bytes from a file descriptor starting at a particular offset.
9125
9126Read length bytes from file descriptor fd, starting at offset bytes from
9127the beginning of the file. The file offset remains unchanged.
9128[clinic start generated code]*/
9129
Larry Hastings2f936352014-08-05 14:04:04 +10009130static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009131os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9132/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009133{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009134 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009135 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009136 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009137
Larry Hastings2f936352014-08-05 14:04:04 +10009138 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009139 errno = EINVAL;
9140 return posix_error();
9141 }
Larry Hastings2f936352014-08-05 14:04:04 +10009142 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009143 if (buffer == NULL)
9144 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009145
9146 do {
9147 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009148 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009149 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009150 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009151 Py_END_ALLOW_THREADS
9152 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9153
Ross Lagerwall7807c352011-03-17 20:20:30 +02009154 if (n < 0) {
9155 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009156 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009157 }
Larry Hastings2f936352014-08-05 14:04:04 +10009158 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009159 _PyBytes_Resize(&buffer, n);
9160 return buffer;
9161}
Larry Hastings2f936352014-08-05 14:04:04 +10009162#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009163
Pablo Galindo4defba32018-01-27 16:16:37 +00009164#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9165/*[clinic input]
9166os.preadv -> Py_ssize_t
9167
9168 fd: int
9169 buffers: object
9170 offset: Py_off_t
9171 flags: int = 0
9172 /
9173
9174Reads from a file descriptor into a number of mutable bytes-like objects.
9175
9176Combines the functionality of readv() and pread(). As readv(), it will
9177transfer data into each buffer until it is full and then move on to the next
9178buffer in the sequence to hold the rest of the data. Its fourth argument,
9179specifies the file offset at which the input operation is to be performed. It
9180will return the total number of bytes read (which can be less than the total
9181capacity of all the objects).
9182
9183The flags argument contains a bitwise OR of zero or more of the following flags:
9184
9185- RWF_HIPRI
9186- RWF_NOWAIT
9187
9188Using non-zero flags requires Linux 4.6 or newer.
9189[clinic start generated code]*/
9190
9191static Py_ssize_t
9192os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9193 int flags)
9194/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9195{
9196 Py_ssize_t cnt, n;
9197 int async_err = 0;
9198 struct iovec *iov;
9199 Py_buffer *buf;
9200
9201 if (!PySequence_Check(buffers)) {
9202 PyErr_SetString(PyExc_TypeError,
9203 "preadv2() arg 2 must be a sequence");
9204 return -1;
9205 }
9206
9207 cnt = PySequence_Size(buffers);
9208 if (cnt < 0) {
9209 return -1;
9210 }
9211
9212#ifndef HAVE_PREADV2
9213 if(flags != 0) {
9214 argument_unavailable_error("preadv2", "flags");
9215 return -1;
9216 }
9217#endif
9218
9219 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9220 return -1;
9221 }
9222#ifdef HAVE_PREADV2
9223 do {
9224 Py_BEGIN_ALLOW_THREADS
9225 _Py_BEGIN_SUPPRESS_IPH
9226 n = preadv2(fd, iov, cnt, offset, flags);
9227 _Py_END_SUPPRESS_IPH
9228 Py_END_ALLOW_THREADS
9229 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9230#else
9231 do {
9232 Py_BEGIN_ALLOW_THREADS
9233 _Py_BEGIN_SUPPRESS_IPH
9234 n = preadv(fd, iov, cnt, offset);
9235 _Py_END_SUPPRESS_IPH
9236 Py_END_ALLOW_THREADS
9237 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9238#endif
9239
9240 iov_cleanup(iov, buf, cnt);
9241 if (n < 0) {
9242 if (!async_err) {
9243 posix_error();
9244 }
9245 return -1;
9246 }
9247
9248 return n;
9249}
9250#endif /* HAVE_PREADV */
9251
Larry Hastings2f936352014-08-05 14:04:04 +10009252
9253/*[clinic input]
9254os.write -> Py_ssize_t
9255
9256 fd: int
9257 data: Py_buffer
9258 /
9259
9260Write a bytes object to a file descriptor.
9261[clinic start generated code]*/
9262
Larry Hastings2f936352014-08-05 14:04:04 +10009263static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009264os_write_impl(PyObject *module, int fd, Py_buffer *data)
9265/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009266{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009267 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009268}
9269
9270#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009271#ifdef __APPLE__
9272/*[clinic input]
9273os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009274
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009275 out_fd: int
9276 in_fd: int
9277 offset: Py_off_t
9278 count as sbytes: Py_off_t
9279 headers: object(c_default="NULL") = ()
9280 trailers: object(c_default="NULL") = ()
9281 flags: int = 0
9282
9283Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9284[clinic start generated code]*/
9285
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009286static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009287os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9288 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9289 int flags)
9290/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9291#elif defined(__FreeBSD__) || defined(__DragonFly__)
9292/*[clinic input]
9293os.sendfile
9294
9295 out_fd: int
9296 in_fd: int
9297 offset: Py_off_t
9298 count: Py_ssize_t
9299 headers: object(c_default="NULL") = ()
9300 trailers: object(c_default="NULL") = ()
9301 flags: int = 0
9302
9303Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9304[clinic start generated code]*/
9305
9306static PyObject *
9307os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9308 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9309 int flags)
9310/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9311#else
9312/*[clinic input]
9313os.sendfile
9314
9315 out_fd: int
9316 in_fd: int
9317 offset as offobj: object
9318 count: Py_ssize_t
9319
9320Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9321[clinic start generated code]*/
9322
9323static PyObject *
9324os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9325 Py_ssize_t count)
9326/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9327#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009328{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009329 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009330 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009331
9332#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9333#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009334 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009335#endif
9336 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009337 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009338
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009339 sf.headers = NULL;
9340 sf.trailers = NULL;
9341
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009342 if (headers != NULL) {
9343 if (!PySequence_Check(headers)) {
9344 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009345 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009346 return NULL;
9347 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009348 Py_ssize_t i = PySequence_Size(headers);
9349 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009350 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009351 if (i > INT_MAX) {
9352 PyErr_SetString(PyExc_OverflowError,
9353 "sendfile() header is too large");
9354 return NULL;
9355 }
9356 if (i > 0) {
9357 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009358 if (iov_setup(&(sf.headers), &hbuf,
9359 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009360 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009361#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009362 for (i = 0; i < sf.hdr_cnt; i++) {
9363 Py_ssize_t blen = sf.headers[i].iov_len;
9364# define OFF_T_MAX 0x7fffffffffffffff
9365 if (sbytes >= OFF_T_MAX - blen) {
9366 PyErr_SetString(PyExc_OverflowError,
9367 "sendfile() header is too large");
9368 return NULL;
9369 }
9370 sbytes += blen;
9371 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009372#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009373 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009374 }
9375 }
9376 if (trailers != NULL) {
9377 if (!PySequence_Check(trailers)) {
9378 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009379 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009380 return NULL;
9381 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009382 Py_ssize_t i = PySequence_Size(trailers);
9383 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009384 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009385 if (i > INT_MAX) {
9386 PyErr_SetString(PyExc_OverflowError,
9387 "sendfile() trailer is too large");
9388 return NULL;
9389 }
9390 if (i > 0) {
9391 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009392 if (iov_setup(&(sf.trailers), &tbuf,
9393 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009394 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009395 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009396 }
9397 }
9398
Steve Dower8fc89802015-04-12 00:26:27 -04009399 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009400 do {
9401 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009402#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009403 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009404#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009405 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009406#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009407 Py_END_ALLOW_THREADS
9408 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009409 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009410
9411 if (sf.headers != NULL)
9412 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9413 if (sf.trailers != NULL)
9414 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9415
9416 if (ret < 0) {
9417 if ((errno == EAGAIN) || (errno == EBUSY)) {
9418 if (sbytes != 0) {
9419 // some data has been sent
9420 goto done;
9421 }
9422 else {
9423 // no data has been sent; upper application is supposed
9424 // to retry on EAGAIN or EBUSY
9425 return posix_error();
9426 }
9427 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009428 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009429 }
9430 goto done;
9431
9432done:
9433 #if !defined(HAVE_LARGEFILE_SUPPORT)
9434 return Py_BuildValue("l", sbytes);
9435 #else
9436 return Py_BuildValue("L", sbytes);
9437 #endif
9438
9439#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009440#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009441 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009442 do {
9443 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009444 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009445 Py_END_ALLOW_THREADS
9446 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009447 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009448 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009449 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009450 }
9451#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009452 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009453 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009454 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009455
Łukasz Langa7e356f12020-09-16 13:52:26 +02009456#if defined(__sun) && defined(__SVR4)
9457 // On Solaris, sendfile raises EINVAL rather than returning 0
9458 // when the offset is equal or bigger than the in_fd size.
9459 int res;
9460 struct stat st;
9461
9462 do {
9463 Py_BEGIN_ALLOW_THREADS
9464 res = fstat(in_fd, &st);
9465 Py_END_ALLOW_THREADS
9466 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9467 if (ret < 0)
9468 return (!async_err) ? posix_error() : NULL;
9469
9470 if (offset >= st.st_size) {
9471 return Py_BuildValue("i", 0);
9472 }
9473#endif
9474
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009475 do {
9476 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009477 ret = sendfile(out_fd, in_fd, &offset, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009478 Py_END_ALLOW_THREADS
9479 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009480 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009481 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009482 return Py_BuildValue("n", ret);
9483#endif
9484}
Larry Hastings2f936352014-08-05 14:04:04 +10009485#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009486
Larry Hastings2f936352014-08-05 14:04:04 +10009487
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009488#if defined(__APPLE__)
9489/*[clinic input]
9490os._fcopyfile
9491
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009492 in_fd: int
9493 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009494 flags: int
9495 /
9496
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009497Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009498[clinic start generated code]*/
9499
9500static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009501os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9502/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009503{
9504 int ret;
9505
9506 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009507 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009508 Py_END_ALLOW_THREADS
9509 if (ret < 0)
9510 return posix_error();
9511 Py_RETURN_NONE;
9512}
9513#endif
9514
9515
Larry Hastings2f936352014-08-05 14:04:04 +10009516/*[clinic input]
9517os.fstat
9518
9519 fd : int
9520
9521Perform a stat system call on the given file descriptor.
9522
9523Like stat(), but for an open file descriptor.
9524Equivalent to os.stat(fd).
9525[clinic start generated code]*/
9526
Larry Hastings2f936352014-08-05 14:04:04 +10009527static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009528os_fstat_impl(PyObject *module, int fd)
9529/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009530{
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 STRUCT_STAT st;
9532 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009533 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009534
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009535 do {
9536 Py_BEGIN_ALLOW_THREADS
9537 res = FSTAT(fd, &st);
9538 Py_END_ALLOW_THREADS
9539 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009541#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009542 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009543#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009544 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009545#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 }
Tim Peters5aa91602002-01-30 05:46:57 +00009547
Victor Stinner1c2fa782020-05-10 11:05:29 +02009548 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009549}
9550
Larry Hastings2f936352014-08-05 14:04:04 +10009551
9552/*[clinic input]
9553os.isatty -> bool
9554 fd: int
9555 /
9556
9557Return True if the fd is connected to a terminal.
9558
9559Return True if the file descriptor is an open file descriptor
9560connected to the slave end of a terminal.
9561[clinic start generated code]*/
9562
Larry Hastings2f936352014-08-05 14:04:04 +10009563static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009564os_isatty_impl(PyObject *module, int fd)
9565/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009566{
Steve Dower8fc89802015-04-12 00:26:27 -04009567 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009568 _Py_BEGIN_SUPPRESS_IPH
9569 return_value = isatty(fd);
9570 _Py_END_SUPPRESS_IPH
9571 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009572}
9573
9574
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009575#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009576/*[clinic input]
9577os.pipe
9578
9579Create a pipe.
9580
9581Returns a tuple of two file descriptors:
9582 (read_fd, write_fd)
9583[clinic start generated code]*/
9584
Larry Hastings2f936352014-08-05 14:04:04 +10009585static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009586os_pipe_impl(PyObject *module)
9587/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009588{
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02009590#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009592 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009594#else
9595 int res;
9596#endif
9597
9598#ifdef MS_WINDOWS
9599 attr.nLength = sizeof(attr);
9600 attr.lpSecurityDescriptor = NULL;
9601 attr.bInheritHandle = FALSE;
9602
9603 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08009604 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009605 ok = CreatePipe(&read, &write, &attr, 0);
9606 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07009607 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
9608 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009609 if (fds[0] == -1 || fds[1] == -1) {
9610 CloseHandle(read);
9611 CloseHandle(write);
9612 ok = 0;
9613 }
9614 }
Steve Dowerc3630612016-11-19 18:41:16 -08009615 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009616 Py_END_ALLOW_THREADS
9617
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01009619 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02009620#else
9621
9622#ifdef HAVE_PIPE2
9623 Py_BEGIN_ALLOW_THREADS
9624 res = pipe2(fds, O_CLOEXEC);
9625 Py_END_ALLOW_THREADS
9626
9627 if (res != 0 && errno == ENOSYS)
9628 {
9629#endif
9630 Py_BEGIN_ALLOW_THREADS
9631 res = pipe(fds);
9632 Py_END_ALLOW_THREADS
9633
9634 if (res == 0) {
9635 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
9636 close(fds[0]);
9637 close(fds[1]);
9638 return NULL;
9639 }
9640 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
9641 close(fds[0]);
9642 close(fds[1]);
9643 return NULL;
9644 }
9645 }
9646#ifdef HAVE_PIPE2
9647 }
9648#endif
9649
9650 if (res != 0)
9651 return PyErr_SetFromErrno(PyExc_OSError);
9652#endif /* !MS_WINDOWS */
9653 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00009654}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009655#endif /* HAVE_PIPE */
9656
Larry Hastings2f936352014-08-05 14:04:04 +10009657
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009658#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10009659/*[clinic input]
9660os.pipe2
9661
9662 flags: int
9663 /
9664
9665Create a pipe with flags set atomically.
9666
9667Returns a tuple of two file descriptors:
9668 (read_fd, write_fd)
9669
9670flags can be constructed by ORing together one or more of these values:
9671O_NONBLOCK, O_CLOEXEC.
9672[clinic start generated code]*/
9673
Larry Hastings2f936352014-08-05 14:04:04 +10009674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009675os_pipe2_impl(PyObject *module, int flags)
9676/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009677{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009678 int fds[2];
9679 int res;
9680
Charles-François Natalidaafdd52011-05-29 20:07:40 +02009681 res = pipe2(fds, flags);
9682 if (res != 0)
9683 return posix_error();
9684 return Py_BuildValue("(ii)", fds[0], fds[1]);
9685}
9686#endif /* HAVE_PIPE2 */
9687
Larry Hastings2f936352014-08-05 14:04:04 +10009688
Ross Lagerwall7807c352011-03-17 20:20:30 +02009689#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10009690/*[clinic input]
9691os.writev -> Py_ssize_t
9692 fd: int
9693 buffers: object
9694 /
9695
9696Iterate over buffers, and write the contents of each to a file descriptor.
9697
9698Returns the total number of bytes written.
9699buffers must be a sequence of bytes-like objects.
9700[clinic start generated code]*/
9701
Larry Hastings2f936352014-08-05 14:04:04 +10009702static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009703os_writev_impl(PyObject *module, int fd, PyObject *buffers)
9704/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009705{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009706 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10009707 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009708 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009709 struct iovec *iov;
9710 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10009711
9712 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009713 PyErr_SetString(PyExc_TypeError,
9714 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009715 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009716 }
Larry Hastings2f936352014-08-05 14:04:04 +10009717 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009718 if (cnt < 0)
9719 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009720
Larry Hastings2f936352014-08-05 14:04:04 +10009721 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9722 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009723 }
9724
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009725 do {
9726 Py_BEGIN_ALLOW_THREADS
9727 result = writev(fd, iov, cnt);
9728 Py_END_ALLOW_THREADS
9729 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009730
9731 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009732 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009733 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01009734
Georg Brandl306336b2012-06-24 12:55:33 +02009735 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009736}
Larry Hastings2f936352014-08-05 14:04:04 +10009737#endif /* HAVE_WRITEV */
9738
9739
9740#ifdef HAVE_PWRITE
9741/*[clinic input]
9742os.pwrite -> Py_ssize_t
9743
9744 fd: int
9745 buffer: Py_buffer
9746 offset: Py_off_t
9747 /
9748
9749Write bytes to a file descriptor starting at a particular offset.
9750
9751Write buffer to fd, starting at offset bytes from the beginning of
9752the file. Returns the number of bytes writte. Does not change the
9753current file offset.
9754[clinic start generated code]*/
9755
Larry Hastings2f936352014-08-05 14:04:04 +10009756static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009757os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
9758/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009759{
9760 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009761 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009762
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009763 do {
9764 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009765 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009766 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009767 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009768 Py_END_ALLOW_THREADS
9769 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009770
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009771 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10009772 posix_error();
9773 return size;
9774}
9775#endif /* HAVE_PWRITE */
9776
Pablo Galindo4defba32018-01-27 16:16:37 +00009777#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9778/*[clinic input]
9779os.pwritev -> Py_ssize_t
9780
9781 fd: int
9782 buffers: object
9783 offset: Py_off_t
9784 flags: int = 0
9785 /
9786
9787Writes the contents of bytes-like objects to a file descriptor at a given offset.
9788
9789Combines the functionality of writev() and pwrite(). All buffers must be a sequence
9790of bytes-like objects. Buffers are processed in array order. Entire contents of first
9791buffer is written before proceeding to second, and so on. The operating system may
9792set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
9793This function writes the contents of each object to the file descriptor and returns
9794the total number of bytes written.
9795
9796The flags argument contains a bitwise OR of zero or more of the following flags:
9797
9798- RWF_DSYNC
9799- RWF_SYNC
9800
9801Using non-zero flags requires Linux 4.7 or newer.
9802[clinic start generated code]*/
9803
9804static Py_ssize_t
9805os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9806 int flags)
9807/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
9808{
9809 Py_ssize_t cnt;
9810 Py_ssize_t result;
9811 int async_err = 0;
9812 struct iovec *iov;
9813 Py_buffer *buf;
9814
9815 if (!PySequence_Check(buffers)) {
9816 PyErr_SetString(PyExc_TypeError,
9817 "pwritev() arg 2 must be a sequence");
9818 return -1;
9819 }
9820
9821 cnt = PySequence_Size(buffers);
9822 if (cnt < 0) {
9823 return -1;
9824 }
9825
9826#ifndef HAVE_PWRITEV2
9827 if(flags != 0) {
9828 argument_unavailable_error("pwritev2", "flags");
9829 return -1;
9830 }
9831#endif
9832
9833 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
9834 return -1;
9835 }
9836#ifdef HAVE_PWRITEV2
9837 do {
9838 Py_BEGIN_ALLOW_THREADS
9839 _Py_BEGIN_SUPPRESS_IPH
9840 result = pwritev2(fd, iov, cnt, offset, flags);
9841 _Py_END_SUPPRESS_IPH
9842 Py_END_ALLOW_THREADS
9843 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9844#else
9845 do {
9846 Py_BEGIN_ALLOW_THREADS
9847 _Py_BEGIN_SUPPRESS_IPH
9848 result = pwritev(fd, iov, cnt, offset);
9849 _Py_END_SUPPRESS_IPH
9850 Py_END_ALLOW_THREADS
9851 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9852#endif
9853
9854 iov_cleanup(iov, buf, cnt);
9855 if (result < 0) {
9856 if (!async_err) {
9857 posix_error();
9858 }
9859 return -1;
9860 }
9861
9862 return result;
9863}
9864#endif /* HAVE_PWRITEV */
9865
Pablo Galindoaac4d032019-05-31 19:39:47 +01009866#ifdef HAVE_COPY_FILE_RANGE
9867/*[clinic input]
9868
9869os.copy_file_range
9870 src: int
9871 Source file descriptor.
9872 dst: int
9873 Destination file descriptor.
9874 count: Py_ssize_t
9875 Number of bytes to copy.
9876 offset_src: object = None
9877 Starting offset in src.
9878 offset_dst: object = None
9879 Starting offset in dst.
9880
9881Copy count bytes from one file descriptor to another.
9882
9883If offset_src is None, then src is read from the current position;
9884respectively for offset_dst.
9885[clinic start generated code]*/
9886
9887static PyObject *
9888os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
9889 PyObject *offset_src, PyObject *offset_dst)
9890/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
9891{
9892 off_t offset_src_val, offset_dst_val;
9893 off_t *p_offset_src = NULL;
9894 off_t *p_offset_dst = NULL;
9895 Py_ssize_t ret;
9896 int async_err = 0;
9897 /* The flags argument is provided to allow
9898 * for future extensions and currently must be to 0. */
9899 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +00009900
9901
Pablo Galindoaac4d032019-05-31 19:39:47 +01009902 if (count < 0) {
9903 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
9904 return NULL;
9905 }
9906
9907 if (offset_src != Py_None) {
9908 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
9909 return NULL;
9910 }
9911 p_offset_src = &offset_src_val;
9912 }
9913
9914 if (offset_dst != Py_None) {
9915 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
9916 return NULL;
9917 }
9918 p_offset_dst = &offset_dst_val;
9919 }
9920
9921 do {
9922 Py_BEGIN_ALLOW_THREADS
9923 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
9924 Py_END_ALLOW_THREADS
9925 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9926
9927 if (ret < 0) {
9928 return (!async_err) ? posix_error() : NULL;
9929 }
9930
9931 return PyLong_FromSsize_t(ret);
9932}
9933#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +10009934
9935#ifdef HAVE_MKFIFO
9936/*[clinic input]
9937os.mkfifo
9938
9939 path: path_t
9940 mode: int=0o666
9941 *
9942 dir_fd: dir_fd(requires='mkfifoat')=None
9943
9944Create a "fifo" (a POSIX named pipe).
9945
9946If dir_fd is not None, it should be a file descriptor open to a directory,
9947 and path should be relative; path will then be relative to that directory.
9948dir_fd may not be implemented on your platform.
9949 If it is unavailable, using it will raise a NotImplementedError.
9950[clinic start generated code]*/
9951
Larry Hastings2f936352014-08-05 14:04:04 +10009952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009953os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
9954/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009955{
9956 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009957 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009958
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009959 do {
9960 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009961#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009962 if (dir_fd != DEFAULT_DIR_FD)
9963 result = mkfifoat(dir_fd, path->narrow, mode);
9964 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02009965#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009966 result = mkfifo(path->narrow, mode);
9967 Py_END_ALLOW_THREADS
9968 } while (result != 0 && errno == EINTR &&
9969 !(async_err = PyErr_CheckSignals()));
9970 if (result != 0)
9971 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009972
9973 Py_RETURN_NONE;
9974}
9975#endif /* HAVE_MKFIFO */
9976
9977
9978#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
9979/*[clinic input]
9980os.mknod
9981
9982 path: path_t
9983 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02009984 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10009985 *
9986 dir_fd: dir_fd(requires='mknodat')=None
9987
9988Create a node in the file system.
9989
9990Create a node in the file system (file, device special file or named pipe)
9991at path. mode specifies both the permissions to use and the
9992type of node to be created, being combined (bitwise OR) with one of
9993S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
9994device defines the newly created device special file (probably using
9995os.makedev()). Otherwise device is ignored.
9996
9997If dir_fd is not None, it should be a file descriptor open to a directory,
9998 and path should be relative; path will then be relative to that directory.
9999dir_fd may not be implemented on your platform.
10000 If it is unavailable, using it will raise a NotImplementedError.
10001[clinic start generated code]*/
10002
Larry Hastings2f936352014-08-05 14:04:04 +100010003static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010004os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -040010005 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010006/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010007{
10008 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010009 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010010
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010011 do {
10012 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010013#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010014 if (dir_fd != DEFAULT_DIR_FD)
10015 result = mknodat(dir_fd, path->narrow, mode, device);
10016 else
Larry Hastings2f936352014-08-05 14:04:04 +100010017#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010018 result = mknod(path->narrow, mode, device);
10019 Py_END_ALLOW_THREADS
10020 } while (result != 0 && errno == EINTR &&
10021 !(async_err = PyErr_CheckSignals()));
10022 if (result != 0)
10023 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010024
10025 Py_RETURN_NONE;
10026}
10027#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10028
10029
10030#ifdef HAVE_DEVICE_MACROS
10031/*[clinic input]
10032os.major -> unsigned_int
10033
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010034 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010035 /
10036
10037Extracts a device major number from a raw device number.
10038[clinic start generated code]*/
10039
Larry Hastings2f936352014-08-05 14:04:04 +100010040static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010041os_major_impl(PyObject *module, dev_t device)
10042/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010043{
10044 return major(device);
10045}
10046
10047
10048/*[clinic input]
10049os.minor -> unsigned_int
10050
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010051 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010052 /
10053
10054Extracts a device minor number from a raw device number.
10055[clinic start generated code]*/
10056
Larry Hastings2f936352014-08-05 14:04:04 +100010057static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010058os_minor_impl(PyObject *module, dev_t device)
10059/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010060{
10061 return minor(device);
10062}
10063
10064
10065/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010066os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010067
10068 major: int
10069 minor: int
10070 /
10071
10072Composes a raw device number from the major and minor device numbers.
10073[clinic start generated code]*/
10074
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010075static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010076os_makedev_impl(PyObject *module, int major, int minor)
10077/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010078{
10079 return makedev(major, minor);
10080}
10081#endif /* HAVE_DEVICE_MACROS */
10082
10083
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010084#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010085/*[clinic input]
10086os.ftruncate
10087
10088 fd: int
10089 length: Py_off_t
10090 /
10091
10092Truncate a file, specified by file descriptor, to a specific length.
10093[clinic start generated code]*/
10094
Larry Hastings2f936352014-08-05 14:04:04 +100010095static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010096os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10097/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010098{
10099 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010100 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010101
Steve Dowerb82e17e2019-05-23 08:45:22 -070010102 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10103 return NULL;
10104 }
10105
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010106 do {
10107 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010108 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010109#ifdef MS_WINDOWS
10110 result = _chsize_s(fd, length);
10111#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010112 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010113#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010114 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010115 Py_END_ALLOW_THREADS
10116 } while (result != 0 && errno == EINTR &&
10117 !(async_err = PyErr_CheckSignals()));
10118 if (result != 0)
10119 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010120 Py_RETURN_NONE;
10121}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010122#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010123
10124
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010125#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010126/*[clinic input]
10127os.truncate
10128 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10129 length: Py_off_t
10130
10131Truncate a file, specified by path, to a specific length.
10132
10133On some platforms, path may also be specified as an open file descriptor.
10134 If this functionality is unavailable, using it raises an exception.
10135[clinic start generated code]*/
10136
Larry Hastings2f936352014-08-05 14:04:04 +100010137static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010138os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10139/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010140{
10141 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010142#ifdef MS_WINDOWS
10143 int fd;
10144#endif
10145
10146 if (path->fd != -1)
10147 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010148
Steve Dowerb82e17e2019-05-23 08:45:22 -070010149 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10150 return NULL;
10151 }
10152
Larry Hastings2f936352014-08-05 14:04:04 +100010153 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010154 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010155#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010156 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010157 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010158 result = -1;
10159 else {
10160 result = _chsize_s(fd, length);
10161 close(fd);
10162 if (result < 0)
10163 errno = result;
10164 }
10165#else
10166 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010167#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010168 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010169 Py_END_ALLOW_THREADS
10170 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010171 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010172
10173 Py_RETURN_NONE;
10174}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010175#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010176
Ross Lagerwall7807c352011-03-17 20:20:30 +020010177
Victor Stinnerd6b17692014-09-30 12:20:05 +020010178/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10179 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10180 defined, which is the case in Python on AIX. AIX bug report:
10181 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10182#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10183# define POSIX_FADVISE_AIX_BUG
10184#endif
10185
Victor Stinnerec39e262014-09-30 12:35:58 +020010186
Victor Stinnerd6b17692014-09-30 12:20:05 +020010187#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010188/*[clinic input]
10189os.posix_fallocate
10190
10191 fd: int
10192 offset: Py_off_t
10193 length: Py_off_t
10194 /
10195
10196Ensure a file has allocated at least a particular number of bytes on disk.
10197
10198Ensure that the file specified by fd encompasses a range of bytes
10199starting at offset bytes from the beginning and continuing for length bytes.
10200[clinic start generated code]*/
10201
Larry Hastings2f936352014-08-05 14:04:04 +100010202static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010203os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010204 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010205/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010206{
10207 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010208 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010209
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010210 do {
10211 Py_BEGIN_ALLOW_THREADS
10212 result = posix_fallocate(fd, offset, length);
10213 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010214 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10215
10216 if (result == 0)
10217 Py_RETURN_NONE;
10218
10219 if (async_err)
10220 return NULL;
10221
10222 errno = result;
10223 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010224}
Victor Stinnerec39e262014-09-30 12:35:58 +020010225#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010226
Ross Lagerwall7807c352011-03-17 20:20:30 +020010227
Victor Stinnerd6b17692014-09-30 12:20:05 +020010228#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010229/*[clinic input]
10230os.posix_fadvise
10231
10232 fd: int
10233 offset: Py_off_t
10234 length: Py_off_t
10235 advice: int
10236 /
10237
10238Announce an intention to access data in a specific pattern.
10239
10240Announce an intention to access data in a specific pattern, thus allowing
10241the kernel to make optimizations.
10242The advice applies to the region of the file specified by fd starting at
10243offset and continuing for length bytes.
10244advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10245POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10246POSIX_FADV_DONTNEED.
10247[clinic start generated code]*/
10248
Larry Hastings2f936352014-08-05 14:04:04 +100010249static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010250os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010251 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010252/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010253{
10254 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010255 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010256
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010257 do {
10258 Py_BEGIN_ALLOW_THREADS
10259 result = posix_fadvise(fd, offset, length, advice);
10260 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010261 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10262
10263 if (result == 0)
10264 Py_RETURN_NONE;
10265
10266 if (async_err)
10267 return NULL;
10268
10269 errno = result;
10270 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010271}
Victor Stinnerec39e262014-09-30 12:35:58 +020010272#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010273
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010274
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010275#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010276static PyObject*
10277win32_putenv(PyObject *name, PyObject *value)
10278{
10279 /* Search from index 1 because on Windows starting '=' is allowed for
10280 defining hidden environment variables. */
10281 if (PyUnicode_GET_LENGTH(name) == 0 ||
10282 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10283 {
10284 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10285 return NULL;
10286 }
10287 PyObject *unicode;
10288 if (value != NULL) {
10289 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10290 }
10291 else {
10292 unicode = PyUnicode_FromFormat("%U=", name);
10293 }
10294 if (unicode == NULL) {
10295 return NULL;
10296 }
10297
10298 Py_ssize_t size;
10299 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10300 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10301 Py_DECREF(unicode);
10302
10303 if (env == NULL) {
10304 return NULL;
10305 }
10306 if (size > _MAX_ENV) {
10307 PyErr_Format(PyExc_ValueError,
10308 "the environment variable is longer than %u characters",
10309 _MAX_ENV);
10310 PyMem_Free(env);
10311 return NULL;
10312 }
10313
10314 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10315 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10316 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10317
10318 Prefer _wputenv() to be compatible with C libraries using CRT
10319 variables and CRT functions using these variables (ex: getenv()). */
10320 int err = _wputenv(env);
10321 PyMem_Free(env);
10322
10323 if (err) {
10324 posix_error();
10325 return NULL;
10326 }
10327
10328 Py_RETURN_NONE;
10329}
10330#endif
10331
10332
10333#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010334/*[clinic input]
10335os.putenv
10336
10337 name: unicode
10338 value: unicode
10339 /
10340
10341Change or add an environment variable.
10342[clinic start generated code]*/
10343
Larry Hastings2f936352014-08-05 14:04:04 +100010344static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010345os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10346/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010347{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010348 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10349 return NULL;
10350 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010351 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010352}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010353#else
Larry Hastings2f936352014-08-05 14:04:04 +100010354/*[clinic input]
10355os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010356
Larry Hastings2f936352014-08-05 14:04:04 +100010357 name: FSConverter
10358 value: FSConverter
10359 /
10360
10361Change or add an environment variable.
10362[clinic start generated code]*/
10363
Larry Hastings2f936352014-08-05 14:04:04 +100010364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010365os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10366/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010367{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010368 const char *name_string = PyBytes_AS_STRING(name);
10369 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010370
Serhiy Storchaka77703942017-06-25 07:33:01 +030010371 if (strchr(name_string, '=') != NULL) {
10372 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10373 return NULL;
10374 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010375
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010376 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10377 return NULL;
10378 }
10379
Victor Stinnerb477d192020-01-22 22:48:16 +010010380 if (setenv(name_string, value_string, 1)) {
10381 return posix_error();
10382 }
Larry Hastings2f936352014-08-05 14:04:04 +100010383 Py_RETURN_NONE;
10384}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010385#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010386
10387
Victor Stinner161e7b32020-01-24 11:53:44 +010010388#ifdef MS_WINDOWS
10389/*[clinic input]
10390os.unsetenv
10391 name: unicode
10392 /
10393
10394Delete an environment variable.
10395[clinic start generated code]*/
10396
10397static PyObject *
10398os_unsetenv_impl(PyObject *module, PyObject *name)
10399/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10400{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010401 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10402 return NULL;
10403 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010404 return win32_putenv(name, NULL);
10405}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010406#else
Larry Hastings2f936352014-08-05 14:04:04 +100010407/*[clinic input]
10408os.unsetenv
10409 name: FSConverter
10410 /
10411
10412Delete an environment variable.
10413[clinic start generated code]*/
10414
Larry Hastings2f936352014-08-05 14:04:04 +100010415static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010416os_unsetenv_impl(PyObject *module, PyObject *name)
10417/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010418{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010419 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10420 return NULL;
10421 }
Victor Stinner984890f2011-11-24 13:53:38 +010010422#ifdef HAVE_BROKEN_UNSETENV
10423 unsetenv(PyBytes_AS_STRING(name));
10424#else
Victor Stinner161e7b32020-01-24 11:53:44 +010010425 int err = unsetenv(PyBytes_AS_STRING(name));
10426 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010010427 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010010428 }
Victor Stinner984890f2011-11-24 13:53:38 +010010429#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010430
Victor Stinner84ae1182010-05-06 22:05:07 +000010431 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010432}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010433#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000010434
Larry Hastings2f936352014-08-05 14:04:04 +100010435
10436/*[clinic input]
10437os.strerror
10438
10439 code: int
10440 /
10441
10442Translate an error code to a message string.
10443[clinic start generated code]*/
10444
Larry Hastings2f936352014-08-05 14:04:04 +100010445static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010446os_strerror_impl(PyObject *module, int code)
10447/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010448{
10449 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010450 if (message == NULL) {
10451 PyErr_SetString(PyExc_ValueError,
10452 "strerror() argument out of range");
10453 return NULL;
10454 }
Victor Stinner1b579672011-12-17 05:47:23 +010010455 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010456}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010457
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010458
Guido van Rossumc9641791998-08-04 15:26:23 +000010459#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010460#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010461/*[clinic input]
10462os.WCOREDUMP -> bool
10463
10464 status: int
10465 /
10466
10467Return True if the process returning status was dumped to a core file.
10468[clinic start generated code]*/
10469
Larry Hastings2f936352014-08-05 14:04:04 +100010470static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010471os_WCOREDUMP_impl(PyObject *module, int status)
10472/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010473{
10474 WAIT_TYPE wait_status;
10475 WAIT_STATUS_INT(wait_status) = status;
10476 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010477}
10478#endif /* WCOREDUMP */
10479
Larry Hastings2f936352014-08-05 14:04:04 +100010480
Fred Drake106c1a02002-04-23 15:58:02 +000010481#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010482/*[clinic input]
10483os.WIFCONTINUED -> bool
10484
10485 status: int
10486
10487Return True if a particular process was continued from a job control stop.
10488
10489Return True if the process returning status was continued from a
10490job control stop.
10491[clinic start generated code]*/
10492
Larry Hastings2f936352014-08-05 14:04:04 +100010493static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010494os_WIFCONTINUED_impl(PyObject *module, int status)
10495/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010496{
10497 WAIT_TYPE wait_status;
10498 WAIT_STATUS_INT(wait_status) = status;
10499 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010500}
10501#endif /* WIFCONTINUED */
10502
Larry Hastings2f936352014-08-05 14:04:04 +100010503
Guido van Rossumc9641791998-08-04 15:26:23 +000010504#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100010505/*[clinic input]
10506os.WIFSTOPPED -> bool
10507
10508 status: int
10509
10510Return True if the process returning status was stopped.
10511[clinic start generated code]*/
10512
Larry Hastings2f936352014-08-05 14:04:04 +100010513static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010514os_WIFSTOPPED_impl(PyObject *module, int status)
10515/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010516{
10517 WAIT_TYPE wait_status;
10518 WAIT_STATUS_INT(wait_status) = status;
10519 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010520}
10521#endif /* WIFSTOPPED */
10522
Larry Hastings2f936352014-08-05 14:04:04 +100010523
Guido van Rossumc9641791998-08-04 15:26:23 +000010524#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100010525/*[clinic input]
10526os.WIFSIGNALED -> bool
10527
10528 status: int
10529
10530Return True if the process returning status was terminated by a signal.
10531[clinic start generated code]*/
10532
Larry Hastings2f936352014-08-05 14:04:04 +100010533static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010534os_WIFSIGNALED_impl(PyObject *module, int status)
10535/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010536{
10537 WAIT_TYPE wait_status;
10538 WAIT_STATUS_INT(wait_status) = status;
10539 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010540}
10541#endif /* WIFSIGNALED */
10542
Larry Hastings2f936352014-08-05 14:04:04 +100010543
Guido van Rossumc9641791998-08-04 15:26:23 +000010544#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100010545/*[clinic input]
10546os.WIFEXITED -> bool
10547
10548 status: int
10549
10550Return True if the process returning status exited via the exit() system call.
10551[clinic start generated code]*/
10552
Larry Hastings2f936352014-08-05 14:04:04 +100010553static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010554os_WIFEXITED_impl(PyObject *module, int status)
10555/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010556{
10557 WAIT_TYPE wait_status;
10558 WAIT_STATUS_INT(wait_status) = status;
10559 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010560}
10561#endif /* WIFEXITED */
10562
Larry Hastings2f936352014-08-05 14:04:04 +100010563
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000010564#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100010565/*[clinic input]
10566os.WEXITSTATUS -> int
10567
10568 status: int
10569
10570Return the process return code from status.
10571[clinic start generated code]*/
10572
Larry Hastings2f936352014-08-05 14:04:04 +100010573static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010574os_WEXITSTATUS_impl(PyObject *module, int status)
10575/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010576{
10577 WAIT_TYPE wait_status;
10578 WAIT_STATUS_INT(wait_status) = status;
10579 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010580}
10581#endif /* WEXITSTATUS */
10582
Larry Hastings2f936352014-08-05 14:04:04 +100010583
Guido van Rossumc9641791998-08-04 15:26:23 +000010584#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010585/*[clinic input]
10586os.WTERMSIG -> int
10587
10588 status: int
10589
10590Return the signal that terminated the process that provided the status value.
10591[clinic start generated code]*/
10592
Larry Hastings2f936352014-08-05 14:04:04 +100010593static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010594os_WTERMSIG_impl(PyObject *module, int status)
10595/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010596{
10597 WAIT_TYPE wait_status;
10598 WAIT_STATUS_INT(wait_status) = status;
10599 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010600}
10601#endif /* WTERMSIG */
10602
Larry Hastings2f936352014-08-05 14:04:04 +100010603
Guido van Rossumc9641791998-08-04 15:26:23 +000010604#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100010605/*[clinic input]
10606os.WSTOPSIG -> int
10607
10608 status: int
10609
10610Return the signal that stopped the process that provided the status value.
10611[clinic start generated code]*/
10612
Larry Hastings2f936352014-08-05 14:04:04 +100010613static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010614os_WSTOPSIG_impl(PyObject *module, int status)
10615/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010616{
10617 WAIT_TYPE wait_status;
10618 WAIT_STATUS_INT(wait_status) = status;
10619 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000010620}
10621#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000010622#endif /* HAVE_SYS_WAIT_H */
10623
10624
Thomas Wouters477c8d52006-05-27 19:21:47 +000010625#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000010626#ifdef _SCO_DS
10627/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
10628 needed definitions in sys/statvfs.h */
10629#define _SVID3
10630#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010631#include <sys/statvfs.h>
10632
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010633static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020010634_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
10635 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080010636 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 if (v == NULL)
10638 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010639
10640#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010641 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10642 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10643 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
10644 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
10645 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
10646 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
10647 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
10648 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
10649 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10650 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010651#else
Victor Stinner8c62be82010-05-06 00:08:46 +000010652 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
10653 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
10654 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010655 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010657 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010658 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010659 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010660 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010661 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010663 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000010664 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070010665 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
10667 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010668#endif
Michael Felt502d5512018-01-05 13:01:58 +010010669/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
10670 * (issue #32390). */
10671#if defined(_AIX) && defined(_ALL_SOURCE)
10672 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
10673#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010010674 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010010675#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010010676 if (PyErr_Occurred()) {
10677 Py_DECREF(v);
10678 return NULL;
10679 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010680
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010682}
10683
Larry Hastings2f936352014-08-05 14:04:04 +100010684
10685/*[clinic input]
10686os.fstatvfs
10687 fd: int
10688 /
10689
10690Perform an fstatvfs system call on the given fd.
10691
10692Equivalent to statvfs(fd).
10693[clinic start generated code]*/
10694
Larry Hastings2f936352014-08-05 14:04:04 +100010695static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010696os_fstatvfs_impl(PyObject *module, int fd)
10697/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010698{
10699 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010700 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010701 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010702
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010703 do {
10704 Py_BEGIN_ALLOW_THREADS
10705 result = fstatvfs(fd, &st);
10706 Py_END_ALLOW_THREADS
10707 } while (result != 0 && errno == EINTR &&
10708 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010709 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010710 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000010711
Victor Stinner1c2fa782020-05-10 11:05:29 +020010712 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010713}
Larry Hastings2f936352014-08-05 14:04:04 +100010714#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000010715
10716
Thomas Wouters477c8d52006-05-27 19:21:47 +000010717#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000010718#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100010719/*[clinic input]
10720os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000010721
Larry Hastings2f936352014-08-05 14:04:04 +100010722 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
10723
10724Perform a statvfs system call on the given path.
10725
10726path may always be specified as a string.
10727On some platforms, path may also be specified as an open file descriptor.
10728 If this functionality is unavailable, using it raises an exception.
10729[clinic start generated code]*/
10730
Larry Hastings2f936352014-08-05 14:04:04 +100010731static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010732os_statvfs_impl(PyObject *module, path_t *path)
10733/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010734{
10735 int result;
10736 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010737
10738 Py_BEGIN_ALLOW_THREADS
10739#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100010740 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010741#ifdef __APPLE__
10742 /* handle weak-linking on Mac OS X 10.3 */
10743 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +100010744 fd_specified("statvfs", path->fd);
10745 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010746 }
10747#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010748 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010749 }
10750 else
10751#endif
Larry Hastings2f936352014-08-05 14:04:04 +100010752 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753 Py_END_ALLOW_THREADS
10754
10755 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010756 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 }
10758
Victor Stinner1c2fa782020-05-10 11:05:29 +020010759 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000010760}
Larry Hastings2f936352014-08-05 14:04:04 +100010761#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
10762
Guido van Rossum94f6f721999-01-06 18:42:14 +000010763
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010764#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010765/*[clinic input]
10766os._getdiskusage
10767
Steve Dower23ad6d02018-02-22 10:39:10 -080010768 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100010769
10770Return disk usage statistics about the given path as a (total, free) tuple.
10771[clinic start generated code]*/
10772
Larry Hastings2f936352014-08-05 14:04:04 +100010773static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080010774os__getdiskusage_impl(PyObject *module, path_t *path)
10775/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010776{
10777 BOOL retval;
10778 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040010779 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010780
10781 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080010782 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010783 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040010784 if (retval == 0) {
10785 if (GetLastError() == ERROR_DIRECTORY) {
10786 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010787
Joe Pamerc8c02492018-09-25 10:57:36 -040010788 dir_path = PyMem_New(wchar_t, path->length + 1);
10789 if (dir_path == NULL) {
10790 return PyErr_NoMemory();
10791 }
10792
10793 wcscpy_s(dir_path, path->length + 1, path->wide);
10794
10795 if (_dirnameW(dir_path) != -1) {
10796 Py_BEGIN_ALLOW_THREADS
10797 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
10798 Py_END_ALLOW_THREADS
10799 }
10800 /* Record the last error in case it's modified by PyMem_Free. */
10801 err = GetLastError();
10802 PyMem_Free(dir_path);
10803 if (retval) {
10804 goto success;
10805 }
10806 }
10807 return PyErr_SetFromWindowsErr(err);
10808 }
10809
10810success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010811 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
10812}
Larry Hastings2f936352014-08-05 14:04:04 +100010813#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010814
10815
Fred Drakec9680921999-12-13 16:37:25 +000010816/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
10817 * It maps strings representing configuration variable names to
10818 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000010819 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000010820 * rarely-used constants. There are three separate tables that use
10821 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000010822 *
10823 * This code is always included, even if none of the interfaces that
10824 * need it are included. The #if hackery needed to avoid it would be
10825 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000010826 */
10827struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010828 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010829 int value;
Fred Drakec9680921999-12-13 16:37:25 +000010830};
10831
Fred Drake12c6e2d1999-12-14 21:25:03 +000010832static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010833conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000010834 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000010835{
Christian Heimes217cfd12007-12-02 14:31:20 +000010836 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030010837 int value = _PyLong_AsInt(arg);
10838 if (value == -1 && PyErr_Occurred())
10839 return 0;
10840 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000010841 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000010842 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000010843 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000010844 /* look up the value in the table using a binary search */
10845 size_t lo = 0;
10846 size_t mid;
10847 size_t hi = tablesize;
10848 int cmp;
10849 const char *confname;
10850 if (!PyUnicode_Check(arg)) {
10851 PyErr_SetString(PyExc_TypeError,
10852 "configuration names must be strings or integers");
10853 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020010855 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000010856 if (confname == NULL)
10857 return 0;
10858 while (lo < hi) {
10859 mid = (lo + hi) / 2;
10860 cmp = strcmp(confname, table[mid].name);
10861 if (cmp < 0)
10862 hi = mid;
10863 else if (cmp > 0)
10864 lo = mid + 1;
10865 else {
10866 *valuep = table[mid].value;
10867 return 1;
10868 }
10869 }
10870 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
10871 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000010873}
10874
10875
10876#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
10877static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000010878#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010880#endif
10881#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010883#endif
Fred Drakec9680921999-12-13 16:37:25 +000010884#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010886#endif
10887#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000010889#endif
10890#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000010892#endif
10893#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000010895#endif
10896#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010898#endif
10899#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000010901#endif
10902#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000010904#endif
10905#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010907#endif
10908#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000010910#endif
10911#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010913#endif
10914#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000010916#endif
10917#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010919#endif
10920#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000010922#endif
10923#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010925#endif
10926#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000010928#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000010929#ifdef _PC_ACL_ENABLED
10930 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
10931#endif
10932#ifdef _PC_MIN_HOLE_SIZE
10933 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
10934#endif
10935#ifdef _PC_ALLOC_SIZE_MIN
10936 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
10937#endif
10938#ifdef _PC_REC_INCR_XFER_SIZE
10939 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
10940#endif
10941#ifdef _PC_REC_MAX_XFER_SIZE
10942 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
10943#endif
10944#ifdef _PC_REC_MIN_XFER_SIZE
10945 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
10946#endif
10947#ifdef _PC_REC_XFER_ALIGN
10948 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
10949#endif
10950#ifdef _PC_SYMLINK_MAX
10951 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
10952#endif
10953#ifdef _PC_XATTR_ENABLED
10954 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
10955#endif
10956#ifdef _PC_XATTR_EXISTS
10957 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
10958#endif
10959#ifdef _PC_TIMESTAMP_RESOLUTION
10960 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
10961#endif
Fred Drakec9680921999-12-13 16:37:25 +000010962};
10963
Fred Drakec9680921999-12-13 16:37:25 +000010964static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010965conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010966{
10967 return conv_confname(arg, valuep, posix_constants_pathconf,
10968 sizeof(posix_constants_pathconf)
10969 / sizeof(struct constdef));
10970}
10971#endif
10972
Larry Hastings2f936352014-08-05 14:04:04 +100010973
Fred Drakec9680921999-12-13 16:37:25 +000010974#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100010975/*[clinic input]
10976os.fpathconf -> long
10977
10978 fd: int
10979 name: path_confname
10980 /
10981
10982Return the configuration limit name for the file descriptor fd.
10983
10984If there is no limit, return -1.
10985[clinic start generated code]*/
10986
Larry Hastings2f936352014-08-05 14:04:04 +100010987static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010988os_fpathconf_impl(PyObject *module, int fd, int name)
10989/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010990{
10991 long limit;
10992
10993 errno = 0;
10994 limit = fpathconf(fd, name);
10995 if (limit == -1 && errno != 0)
10996 posix_error();
10997
10998 return limit;
10999}
11000#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011001
11002
11003#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011004/*[clinic input]
11005os.pathconf -> long
11006 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
11007 name: path_confname
11008
11009Return the configuration limit name for the file or directory path.
11010
11011If there is no limit, return -1.
11012On some platforms, path may also be specified as an open file descriptor.
11013 If this functionality is unavailable, using it raises an exception.
11014[clinic start generated code]*/
11015
Larry Hastings2f936352014-08-05 14:04:04 +100011016static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011017os_pathconf_impl(PyObject *module, path_t *path, int name)
11018/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011019{
Victor Stinner8c62be82010-05-06 00:08:46 +000011020 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000011021
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020011023#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011024 if (path->fd != -1)
11025 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011026 else
11027#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011028 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 if (limit == -1 && errno != 0) {
11030 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011031 /* could be a path or name problem */
11032 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011033 else
Larry Hastings2f936352014-08-05 14:04:04 +100011034 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 }
Larry Hastings2f936352014-08-05 14:04:04 +100011036
11037 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011038}
Larry Hastings2f936352014-08-05 14:04:04 +100011039#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011040
11041#ifdef HAVE_CONFSTR
11042static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011043#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011045#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011046#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011048#endif
11049#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011051#endif
Fred Draked86ed291999-12-15 15:34:33 +000011052#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011054#endif
11055#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011057#endif
11058#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011060#endif
11061#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011063#endif
Fred Drakec9680921999-12-13 16:37:25 +000011064#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011066#endif
11067#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011069#endif
11070#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011072#endif
11073#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011075#endif
11076#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011078#endif
11079#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011081#endif
11082#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011084#endif
11085#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011087#endif
Fred Draked86ed291999-12-15 15:34:33 +000011088#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011090#endif
Fred Drakec9680921999-12-13 16:37:25 +000011091#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011093#endif
Fred Draked86ed291999-12-15 15:34:33 +000011094#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011096#endif
11097#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011099#endif
11100#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011102#endif
11103#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011105#endif
Fred Drakec9680921999-12-13 16:37:25 +000011106#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011108#endif
11109#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011111#endif
11112#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011114#endif
11115#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011117#endif
11118#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011120#endif
11121#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011123#endif
11124#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011126#endif
11127#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011129#endif
11130#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011132#endif
11133#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011135#endif
11136#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011138#endif
11139#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011141#endif
11142#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011144#endif
11145#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011147#endif
11148#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011150#endif
11151#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011153#endif
Fred Draked86ed291999-12-15 15:34:33 +000011154#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011156#endif
11157#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011158 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011159#endif
11160#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011161 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011162#endif
11163#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011165#endif
11166#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011168#endif
11169#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011171#endif
11172#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011174#endif
11175#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011176 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011177#endif
11178#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011180#endif
11181#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011182 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011183#endif
11184#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011185 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011186#endif
11187#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011188 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011189#endif
11190#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011191 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011192#endif
Fred Drakec9680921999-12-13 16:37:25 +000011193};
11194
11195static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011196conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011197{
11198 return conv_confname(arg, valuep, posix_constants_confstr,
11199 sizeof(posix_constants_confstr)
11200 / sizeof(struct constdef));
11201}
11202
Larry Hastings2f936352014-08-05 14:04:04 +100011203
11204/*[clinic input]
11205os.confstr
11206
11207 name: confstr_confname
11208 /
11209
11210Return a string-valued system configuration variable.
11211[clinic start generated code]*/
11212
Larry Hastings2f936352014-08-05 14:04:04 +100011213static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011214os_confstr_impl(PyObject *module, int name)
11215/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011216{
11217 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011218 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011219 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011220
Victor Stinnercb043522010-09-10 23:49:04 +000011221 errno = 0;
11222 len = confstr(name, buffer, sizeof(buffer));
11223 if (len == 0) {
11224 if (errno) {
11225 posix_error();
11226 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011227 }
11228 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011229 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011230 }
11231 }
Victor Stinnercb043522010-09-10 23:49:04 +000011232
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011233 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011234 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011235 char *buf = PyMem_Malloc(len);
11236 if (buf == NULL)
11237 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011238 len2 = confstr(name, buf, len);
11239 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011240 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011241 PyMem_Free(buf);
11242 }
11243 else
11244 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011245 return result;
11246}
Larry Hastings2f936352014-08-05 14:04:04 +100011247#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011248
11249
11250#ifdef HAVE_SYSCONF
11251static struct constdef posix_constants_sysconf[] = {
11252#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011254#endif
11255#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011257#endif
11258#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011260#endif
11261#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011263#endif
11264#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011266#endif
11267#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011268 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011269#endif
11270#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011272#endif
11273#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011275#endif
11276#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011278#endif
11279#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011281#endif
Fred Draked86ed291999-12-15 15:34:33 +000011282#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011284#endif
11285#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011287#endif
Fred Drakec9680921999-12-13 16:37:25 +000011288#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011290#endif
Fred Drakec9680921999-12-13 16:37:25 +000011291#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011293#endif
11294#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011295 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011296#endif
11297#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011299#endif
11300#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011302#endif
11303#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011305#endif
Fred Draked86ed291999-12-15 15:34:33 +000011306#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011308#endif
Fred Drakec9680921999-12-13 16:37:25 +000011309#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011311#endif
11312#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011314#endif
11315#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011317#endif
11318#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011320#endif
11321#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011323#endif
Fred Draked86ed291999-12-15 15:34:33 +000011324#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011326#endif
Fred Drakec9680921999-12-13 16:37:25 +000011327#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011328 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011329#endif
11330#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011332#endif
11333#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011335#endif
11336#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011338#endif
11339#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011340 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011341#endif
11342#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011343 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011344#endif
11345#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011346 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011347#endif
11348#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011349 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011350#endif
11351#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011352 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011353#endif
11354#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011355 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011356#endif
11357#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011358 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011359#endif
11360#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011362#endif
11363#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011364 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011365#endif
11366#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011367 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011368#endif
11369#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011371#endif
11372#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011373 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011374#endif
11375#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011377#endif
11378#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011380#endif
11381#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011382 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011383#endif
11384#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011386#endif
11387#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011388 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011389#endif
11390#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011392#endif
11393#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011395#endif
Fred Draked86ed291999-12-15 15:34:33 +000011396#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011397 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011398#endif
Fred Drakec9680921999-12-13 16:37:25 +000011399#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011400 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011401#endif
11402#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011403 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011404#endif
11405#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011407#endif
Fred Draked86ed291999-12-15 15:34:33 +000011408#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011409 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011410#endif
Fred Drakec9680921999-12-13 16:37:25 +000011411#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011412 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011413#endif
Fred Draked86ed291999-12-15 15:34:33 +000011414#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011415 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011416#endif
11417#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011418 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011419#endif
Fred Drakec9680921999-12-13 16:37:25 +000011420#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011421 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011422#endif
11423#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011425#endif
11426#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011428#endif
11429#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011430 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011431#endif
Fred Draked86ed291999-12-15 15:34:33 +000011432#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011433 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011434#endif
Fred Drakec9680921999-12-13 16:37:25 +000011435#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011436 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011437#endif
11438#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011439 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011440#endif
11441#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011442 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011443#endif
11444#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011445 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011446#endif
11447#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011448 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011449#endif
11450#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011451 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011452#endif
11453#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011455#endif
Fred Draked86ed291999-12-15 15:34:33 +000011456#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011457 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011458#endif
Fred Drakec9680921999-12-13 16:37:25 +000011459#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011460 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011461#endif
11462#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011464#endif
Fred Draked86ed291999-12-15 15:34:33 +000011465#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011467#endif
Fred Drakec9680921999-12-13 16:37:25 +000011468#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011469 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011470#endif
11471#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011473#endif
11474#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011475 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011476#endif
11477#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011478 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011479#endif
11480#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011481 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011482#endif
11483#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011484 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011485#endif
11486#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011487 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011488#endif
11489#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011490 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011491#endif
11492#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011493 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011494#endif
Fred Draked86ed291999-12-15 15:34:33 +000011495#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011496 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011497#endif
11498#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011499 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011500#endif
Fred Drakec9680921999-12-13 16:37:25 +000011501#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000011502 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000011503#endif
11504#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011505 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011506#endif
11507#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011509#endif
11510#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011511 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011512#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030011513#ifdef _SC_AIX_REALMEM
11514 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
11515#endif
Fred Drakec9680921999-12-13 16:37:25 +000011516#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011517 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011518#endif
11519#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011520 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011521#endif
11522#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000011523 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000011524#endif
11525#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000011527#endif
11528#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011529 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000011530#endif
11531#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000011532 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000011533#endif
11534#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000011535 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000011536#endif
11537#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011538 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000011539#endif
11540#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011541 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000011542#endif
11543#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000011544 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000011545#endif
11546#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000011547 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000011548#endif
11549#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000011550 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000011551#endif
11552#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000011553 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000011554#endif
11555#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011556 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011557#endif
11558#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011559 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011560#endif
11561#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000011562 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000011563#endif
11564#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011565 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011566#endif
11567#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011568 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011569#endif
11570#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000011571 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000011572#endif
11573#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011574 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011575#endif
11576#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011577 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011578#endif
11579#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011580 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000011581#endif
11582#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000011583 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000011584#endif
11585#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011586 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011587#endif
11588#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011589 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011590#endif
11591#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011592 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000011593#endif
11594#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011595 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011596#endif
11597#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011598 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011599#endif
11600#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011601 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011602#endif
11603#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011604 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011605#endif
11606#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011607 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011608#endif
Fred Draked86ed291999-12-15 15:34:33 +000011609#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000011610 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000011611#endif
Fred Drakec9680921999-12-13 16:37:25 +000011612#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000011613 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000011614#endif
11615#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011616 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011617#endif
11618#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000011619 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000011620#endif
11621#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011622 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011623#endif
11624#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011625 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011626#endif
11627#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011628 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011629#endif
11630#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000011631 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000011632#endif
11633#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000011634 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000011635#endif
11636#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011637 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011638#endif
11639#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011640 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011641#endif
11642#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000011643 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000011644#endif
11645#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011646 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000011647#endif
11648#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011649 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000011650#endif
11651#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000011652 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000011653#endif
11654#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000011655 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000011656#endif
11657#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011658 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011659#endif
11660#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011661 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011662#endif
11663#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011664 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000011665#endif
11666#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011667 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011668#endif
11669#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011670 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011671#endif
11672#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011673 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011674#endif
11675#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011676 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011677#endif
11678#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011679 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011680#endif
11681#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011682 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011683#endif
11684#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000011685 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000011686#endif
11687#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011688 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011689#endif
11690#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011691 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011692#endif
11693#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011694 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011695#endif
11696#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011697 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011698#endif
11699#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000011700 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000011701#endif
11702#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011703 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011704#endif
11705#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000011706 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000011707#endif
11708#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011709 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000011710#endif
11711#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000011712 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000011713#endif
11714#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000011715 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000011716#endif
11717#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000011718 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000011719#endif
11720#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011721 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000011722#endif
11723#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000011724 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000011725#endif
11726#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000011727 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000011728#endif
11729#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000011730 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000011731#endif
11732#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011733 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011734#endif
11735#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011736 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011737#endif
11738#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000011739 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000011740#endif
11741#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000011742 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000011743#endif
11744#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000011745 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000011746#endif
11747};
11748
11749static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011750conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011751{
11752 return conv_confname(arg, valuep, posix_constants_sysconf,
11753 sizeof(posix_constants_sysconf)
11754 / sizeof(struct constdef));
11755}
11756
Larry Hastings2f936352014-08-05 14:04:04 +100011757
11758/*[clinic input]
11759os.sysconf -> long
11760 name: sysconf_confname
11761 /
11762
11763Return an integer-valued system configuration variable.
11764[clinic start generated code]*/
11765
Larry Hastings2f936352014-08-05 14:04:04 +100011766static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011767os_sysconf_impl(PyObject *module, int name)
11768/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011769{
11770 long value;
11771
11772 errno = 0;
11773 value = sysconf(name);
11774 if (value == -1 && errno != 0)
11775 posix_error();
11776 return value;
11777}
11778#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011779
11780
Fred Drakebec628d1999-12-15 18:31:10 +000011781/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020011782 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000011783 * the exported dictionaries that are used to publish information about the
11784 * names available on the host platform.
11785 *
11786 * Sorting the table at runtime ensures that the table is properly ordered
11787 * when used, even for platforms we're not able to test on. It also makes
11788 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000011789 */
Fred Drakebec628d1999-12-15 18:31:10 +000011790
11791static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011792cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000011793{
11794 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011795 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000011796 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000011797 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000011798
11799 return strcmp(c1->name, c2->name);
11800}
11801
11802static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011803setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011804 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011805{
Fred Drakebec628d1999-12-15 18:31:10 +000011806 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000011807 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000011808
11809 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
11810 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000011811 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000011812 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011813
Barry Warsaw3155db32000-04-13 15:20:40 +000011814 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000011815 PyObject *o = PyLong_FromLong(table[i].value);
11816 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
11817 Py_XDECREF(o);
11818 Py_DECREF(d);
11819 return -1;
11820 }
11821 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000011822 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000011823 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000011824}
11825
Fred Drakebec628d1999-12-15 18:31:10 +000011826/* Return -1 on failure, 0 on success. */
11827static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011828setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000011829{
11830#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000011831 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000011832 sizeof(posix_constants_pathconf)
11833 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011834 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011835 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011836#endif
11837#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000011838 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000011839 sizeof(posix_constants_confstr)
11840 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011841 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011842 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011843#endif
11844#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000011845 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000011846 sizeof(posix_constants_sysconf)
11847 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000011848 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000011849 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000011850#endif
Fred Drakebec628d1999-12-15 18:31:10 +000011851 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000011852}
Fred Draked86ed291999-12-15 15:34:33 +000011853
11854
Larry Hastings2f936352014-08-05 14:04:04 +100011855/*[clinic input]
11856os.abort
11857
11858Abort the interpreter immediately.
11859
11860This function 'dumps core' or otherwise fails in the hardest way possible
11861on the hosting operating system. This function never returns.
11862[clinic start generated code]*/
11863
Larry Hastings2f936352014-08-05 14:04:04 +100011864static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011865os_abort_impl(PyObject *module)
11866/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011867{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011868 abort();
11869 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010011870#ifndef __clang__
11871 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
11872 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
11873 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011874 Py_FatalError("abort() called from Python code didn't abort!");
11875 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010011876#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011877}
Fred Drakebec628d1999-12-15 18:31:10 +000011878
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011879#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011880/* Grab ShellExecute dynamically from shell32 */
11881static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011882static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
11883 LPCWSTR, INT);
11884static int
11885check_ShellExecute()
11886{
11887 HINSTANCE hShell32;
11888
11889 /* only recheck */
11890 if (-1 == has_ShellExecute) {
11891 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070011892 /* Security note: this call is not vulnerable to "DLL hijacking".
11893 SHELL32 is part of "KnownDLLs" and so Windows always load
11894 the system SHELL32.DLL, even if there is another SHELL32.DLL
11895 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080011896 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080011897 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080011898 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
11899 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070011900 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011901 } else {
11902 has_ShellExecute = 0;
11903 }
Tony Roberts4860f012019-02-02 18:16:42 +010011904 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080011905 }
11906 return has_ShellExecute;
11907}
11908
11909
Steve Dowercc16be82016-09-08 10:35:16 -070011910/*[clinic input]
11911os.startfile
11912 filepath: path_t
11913 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000011914
Steve Dowercc16be82016-09-08 10:35:16 -070011915Start a file with its associated application.
11916
11917When "operation" is not specified or "open", this acts like
11918double-clicking the file in Explorer, or giving the file name as an
11919argument to the DOS "start" command: the file is opened with whatever
11920application (if any) its extension is associated.
11921When another "operation" is given, it specifies what should be done with
11922the file. A typical operation is "print".
11923
11924startfile returns as soon as the associated application is launched.
11925There is no option to wait for the application to close, and no way
11926to retrieve the application's exit status.
11927
11928The filepath is relative to the current directory. If you want to use
11929an absolute path, make sure the first character is not a slash ("/");
11930the underlying Win32 ShellExecute function doesn't work if it is.
11931[clinic start generated code]*/
11932
11933static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020011934os_startfile_impl(PyObject *module, path_t *filepath,
11935 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030011936/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070011937{
11938 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080011939
11940 if(!check_ShellExecute()) {
11941 /* If the OS doesn't have ShellExecute, return a
11942 NotImplementedError. */
11943 return PyErr_Format(PyExc_NotImplementedError,
11944 "startfile not available on this platform");
11945 }
11946
Saiyang Gou7514f4f2020-02-12 23:47:42 -080011947 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080011948 return NULL;
11949 }
11950
Victor Stinner8c62be82010-05-06 00:08:46 +000011951 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070011952 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080011953 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000011954 Py_END_ALLOW_THREADS
11955
Victor Stinner8c62be82010-05-06 00:08:46 +000011956 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070011957 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020011958 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000011959 }
Steve Dowercc16be82016-09-08 10:35:16 -070011960 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000011961}
Larry Hastings2f936352014-08-05 14:04:04 +100011962#endif /* MS_WINDOWS */
11963
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011964
Martin v. Löwis438b5342002-12-27 10:16:42 +000011965#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100011966/*[clinic input]
11967os.getloadavg
11968
11969Return average recent system load information.
11970
11971Return the number of processes in the system run queue averaged over
11972the last 1, 5, and 15 minutes as a tuple of three floats.
11973Raises OSError if the load average was unobtainable.
11974[clinic start generated code]*/
11975
Larry Hastings2f936352014-08-05 14:04:04 +100011976static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011977os_getloadavg_impl(PyObject *module)
11978/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000011979{
11980 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000011981 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000011982 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
11983 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000011984 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000011985 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000011986}
Larry Hastings2f936352014-08-05 14:04:04 +100011987#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000011988
Larry Hastings2f936352014-08-05 14:04:04 +100011989
11990/*[clinic input]
11991os.device_encoding
11992 fd: int
11993
11994Return a string describing the encoding of a terminal's file descriptor.
11995
11996The file descriptor must be attached to a terminal.
11997If the device is not a terminal, return None.
11998[clinic start generated code]*/
11999
Larry Hastings2f936352014-08-05 14:04:04 +100012000static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012001os_device_encoding_impl(PyObject *module, int fd)
12002/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012003{
Brett Cannonefb00c02012-02-29 18:31:31 -050012004 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000012005}
12006
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012007
Larry Hastings2f936352014-08-05 14:04:04 +100012008#ifdef HAVE_SETRESUID
12009/*[clinic input]
12010os.setresuid
12011
12012 ruid: uid_t
12013 euid: uid_t
12014 suid: uid_t
12015 /
12016
12017Set the current process's real, effective, and saved user ids.
12018[clinic start generated code]*/
12019
Larry Hastings2f936352014-08-05 14:04:04 +100012020static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012021os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12022/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012023{
Victor Stinner8c62be82010-05-06 00:08:46 +000012024 if (setresuid(ruid, euid, suid) < 0)
12025 return posix_error();
12026 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012027}
Larry Hastings2f936352014-08-05 14:04:04 +100012028#endif /* HAVE_SETRESUID */
12029
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012030
12031#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012032/*[clinic input]
12033os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012034
Larry Hastings2f936352014-08-05 14:04:04 +100012035 rgid: gid_t
12036 egid: gid_t
12037 sgid: gid_t
12038 /
12039
12040Set the current process's real, effective, and saved group ids.
12041[clinic start generated code]*/
12042
Larry Hastings2f936352014-08-05 14:04:04 +100012043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012044os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12045/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012046{
Victor Stinner8c62be82010-05-06 00:08:46 +000012047 if (setresgid(rgid, egid, sgid) < 0)
12048 return posix_error();
12049 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012050}
Larry Hastings2f936352014-08-05 14:04:04 +100012051#endif /* HAVE_SETRESGID */
12052
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012053
12054#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012055/*[clinic input]
12056os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012057
Larry Hastings2f936352014-08-05 14:04:04 +100012058Return a tuple of the current process's real, effective, and saved user ids.
12059[clinic start generated code]*/
12060
Larry Hastings2f936352014-08-05 14:04:04 +100012061static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012062os_getresuid_impl(PyObject *module)
12063/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012064{
Victor Stinner8c62be82010-05-06 00:08:46 +000012065 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012066 if (getresuid(&ruid, &euid, &suid) < 0)
12067 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012068 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12069 _PyLong_FromUid(euid),
12070 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012071}
Larry Hastings2f936352014-08-05 14:04:04 +100012072#endif /* HAVE_GETRESUID */
12073
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012074
12075#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012076/*[clinic input]
12077os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012078
Larry Hastings2f936352014-08-05 14:04:04 +100012079Return a tuple of the current process's real, effective, and saved group ids.
12080[clinic start generated code]*/
12081
Larry Hastings2f936352014-08-05 14:04:04 +100012082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012083os_getresgid_impl(PyObject *module)
12084/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012085{
12086 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012087 if (getresgid(&rgid, &egid, &sgid) < 0)
12088 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012089 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12090 _PyLong_FromGid(egid),
12091 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012092}
Larry Hastings2f936352014-08-05 14:04:04 +100012093#endif /* HAVE_GETRESGID */
12094
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012095
Benjamin Peterson9428d532011-09-14 11:45:52 -040012096#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012097/*[clinic input]
12098os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012099
Larry Hastings2f936352014-08-05 14:04:04 +100012100 path: path_t(allow_fd=True)
12101 attribute: path_t
12102 *
12103 follow_symlinks: bool = True
12104
12105Return the value of extended attribute attribute on path.
12106
BNMetricsb9427072018-11-02 15:20:19 +000012107path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012108If follow_symlinks is False, and the last element of the path is a symbolic
12109 link, getxattr will examine the symbolic link itself instead of the file
12110 the link points to.
12111
12112[clinic start generated code]*/
12113
Larry Hastings2f936352014-08-05 14:04:04 +100012114static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012115os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012116 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012117/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012118{
12119 Py_ssize_t i;
12120 PyObject *buffer = NULL;
12121
12122 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12123 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012124
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012125 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12126 return NULL;
12127 }
12128
Larry Hastings9cf065c2012-06-22 16:30:09 -070012129 for (i = 0; ; i++) {
12130 void *ptr;
12131 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012132 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012133 Py_ssize_t buffer_size = buffer_sizes[i];
12134 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012135 path_error(path);
12136 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012137 }
12138 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12139 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012140 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012141 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012142
Larry Hastings9cf065c2012-06-22 16:30:09 -070012143 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012144 if (path->fd >= 0)
12145 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012146 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012147 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012148 else
Larry Hastings2f936352014-08-05 14:04:04 +100012149 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012150 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012151
Larry Hastings9cf065c2012-06-22 16:30:09 -070012152 if (result < 0) {
12153 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012154 if (errno == ERANGE)
12155 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012156 path_error(path);
12157 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012158 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012159
Larry Hastings9cf065c2012-06-22 16:30:09 -070012160 if (result != buffer_size) {
12161 /* Can only shrink. */
12162 _PyBytes_Resize(&buffer, result);
12163 }
12164 break;
12165 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012166
Larry Hastings9cf065c2012-06-22 16:30:09 -070012167 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012168}
12169
Larry Hastings2f936352014-08-05 14:04:04 +100012170
12171/*[clinic input]
12172os.setxattr
12173
12174 path: path_t(allow_fd=True)
12175 attribute: path_t
12176 value: Py_buffer
12177 flags: int = 0
12178 *
12179 follow_symlinks: bool = True
12180
12181Set extended attribute attribute on path to value.
12182
BNMetricsb9427072018-11-02 15:20:19 +000012183path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012184If follow_symlinks is False, and the last element of the path is a symbolic
12185 link, setxattr will modify the symbolic link itself instead of the file
12186 the link points to.
12187
12188[clinic start generated code]*/
12189
Benjamin Peterson799bd802011-08-31 22:15:17 -040012190static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012191os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012192 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012193/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012194{
Larry Hastings2f936352014-08-05 14:04:04 +100012195 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012196
Larry Hastings2f936352014-08-05 14:04:04 +100012197 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012198 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012199
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012200 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12201 value->buf, value->len, flags) < 0) {
12202 return NULL;
12203 }
12204
Benjamin Peterson799bd802011-08-31 22:15:17 -040012205 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012206 if (path->fd > -1)
12207 result = fsetxattr(path->fd, attribute->narrow,
12208 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012209 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012210 result = setxattr(path->narrow, attribute->narrow,
12211 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012212 else
Larry Hastings2f936352014-08-05 14:04:04 +100012213 result = lsetxattr(path->narrow, attribute->narrow,
12214 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012215 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012216
Larry Hastings9cf065c2012-06-22 16:30:09 -070012217 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012218 path_error(path);
12219 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012220 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012221
Larry Hastings2f936352014-08-05 14:04:04 +100012222 Py_RETURN_NONE;
12223}
12224
12225
12226/*[clinic input]
12227os.removexattr
12228
12229 path: path_t(allow_fd=True)
12230 attribute: path_t
12231 *
12232 follow_symlinks: bool = True
12233
12234Remove extended attribute attribute on path.
12235
BNMetricsb9427072018-11-02 15:20:19 +000012236path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012237If follow_symlinks is False, and the last element of the path is a symbolic
12238 link, removexattr will modify the symbolic link itself instead of the file
12239 the link points to.
12240
12241[clinic start generated code]*/
12242
Larry Hastings2f936352014-08-05 14:04:04 +100012243static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012244os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012245 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012246/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012247{
12248 ssize_t result;
12249
12250 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12251 return NULL;
12252
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012253 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12254 return NULL;
12255 }
12256
Larry Hastings2f936352014-08-05 14:04:04 +100012257 Py_BEGIN_ALLOW_THREADS;
12258 if (path->fd > -1)
12259 result = fremovexattr(path->fd, attribute->narrow);
12260 else if (follow_symlinks)
12261 result = removexattr(path->narrow, attribute->narrow);
12262 else
12263 result = lremovexattr(path->narrow, attribute->narrow);
12264 Py_END_ALLOW_THREADS;
12265
12266 if (result) {
12267 return path_error(path);
12268 }
12269
12270 Py_RETURN_NONE;
12271}
12272
12273
12274/*[clinic input]
12275os.listxattr
12276
12277 path: path_t(allow_fd=True, nullable=True) = None
12278 *
12279 follow_symlinks: bool = True
12280
12281Return a list of extended attributes on path.
12282
BNMetricsb9427072018-11-02 15:20:19 +000012283path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012284if path is None, listxattr will examine the current directory.
12285If follow_symlinks is False, and the last element of the path is a symbolic
12286 link, listxattr will examine the symbolic link itself instead of the file
12287 the link points to.
12288[clinic start generated code]*/
12289
Larry Hastings2f936352014-08-05 14:04:04 +100012290static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012291os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012292/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012293{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012294 Py_ssize_t i;
12295 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012296 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012297 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012298
Larry Hastings2f936352014-08-05 14:04:04 +100012299 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012300 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012301
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012302 if (PySys_Audit("os.listxattr", "(O)",
12303 path->object ? path->object : Py_None) < 0) {
12304 return NULL;
12305 }
12306
Larry Hastings2f936352014-08-05 14:04:04 +100012307 name = path->narrow ? path->narrow : ".";
12308
Larry Hastings9cf065c2012-06-22 16:30:09 -070012309 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012310 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012311 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012312 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012313 Py_ssize_t buffer_size = buffer_sizes[i];
12314 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012315 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012316 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012317 break;
12318 }
12319 buffer = PyMem_MALLOC(buffer_size);
12320 if (!buffer) {
12321 PyErr_NoMemory();
12322 break;
12323 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012324
Larry Hastings9cf065c2012-06-22 16:30:09 -070012325 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012326 if (path->fd > -1)
12327 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012328 else if (follow_symlinks)
12329 length = listxattr(name, buffer, buffer_size);
12330 else
12331 length = llistxattr(name, buffer, buffer_size);
12332 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012333
Larry Hastings9cf065c2012-06-22 16:30:09 -070012334 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012335 if (errno == ERANGE) {
12336 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012337 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012338 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012339 }
Larry Hastings2f936352014-08-05 14:04:04 +100012340 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012341 break;
12342 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012343
Larry Hastings9cf065c2012-06-22 16:30:09 -070012344 result = PyList_New(0);
12345 if (!result) {
12346 goto exit;
12347 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012348
Larry Hastings9cf065c2012-06-22 16:30:09 -070012349 end = buffer + length;
12350 for (trace = start = buffer; trace != end; trace++) {
12351 if (!*trace) {
12352 int error;
12353 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12354 trace - start);
12355 if (!attribute) {
12356 Py_DECREF(result);
12357 result = NULL;
12358 goto exit;
12359 }
12360 error = PyList_Append(result, attribute);
12361 Py_DECREF(attribute);
12362 if (error) {
12363 Py_DECREF(result);
12364 result = NULL;
12365 goto exit;
12366 }
12367 start = trace + 1;
12368 }
12369 }
12370 break;
12371 }
12372exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012373 if (buffer)
12374 PyMem_FREE(buffer);
12375 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012376}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012377#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012378
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012379
Larry Hastings2f936352014-08-05 14:04:04 +100012380/*[clinic input]
12381os.urandom
12382
12383 size: Py_ssize_t
12384 /
12385
12386Return a bytes object containing random bytes suitable for cryptographic use.
12387[clinic start generated code]*/
12388
Larry Hastings2f936352014-08-05 14:04:04 +100012389static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012390os_urandom_impl(PyObject *module, Py_ssize_t size)
12391/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012392{
12393 PyObject *bytes;
12394 int result;
12395
Georg Brandl2fb477c2012-02-21 00:33:36 +010012396 if (size < 0)
12397 return PyErr_Format(PyExc_ValueError,
12398 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012399 bytes = PyBytes_FromStringAndSize(NULL, size);
12400 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012401 return NULL;
12402
Victor Stinnere66987e2016-09-06 16:33:52 -070012403 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012404 if (result == -1) {
12405 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012406 return NULL;
12407 }
Larry Hastings2f936352014-08-05 14:04:04 +100012408 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012409}
12410
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012411#ifdef HAVE_MEMFD_CREATE
12412/*[clinic input]
12413os.memfd_create
12414
12415 name: FSConverter
12416 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12417
12418[clinic start generated code]*/
12419
12420static PyObject *
12421os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12422/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12423{
12424 int fd;
12425 const char *bytes = PyBytes_AS_STRING(name);
12426 Py_BEGIN_ALLOW_THREADS
12427 fd = memfd_create(bytes, flags);
12428 Py_END_ALLOW_THREADS
12429 if (fd == -1) {
12430 return PyErr_SetFromErrno(PyExc_OSError);
12431 }
12432 return PyLong_FromLong(fd);
12433}
12434#endif
12435
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012436/* Terminal size querying */
12437
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012438PyDoc_STRVAR(TerminalSize_docstring,
12439 "A tuple of (columns, lines) for holding terminal window size");
12440
12441static PyStructSequence_Field TerminalSize_fields[] = {
12442 {"columns", "width of the terminal window in characters"},
12443 {"lines", "height of the terminal window in characters"},
12444 {NULL, NULL}
12445};
12446
12447static PyStructSequence_Desc TerminalSize_desc = {
12448 "os.terminal_size",
12449 TerminalSize_docstring,
12450 TerminalSize_fields,
12451 2,
12452};
12453
12454#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012455/*[clinic input]
12456os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012457
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012458 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
12459 /
12460
12461Return the size of the terminal window as (columns, lines).
12462
12463The optional argument fd (default standard output) specifies
12464which file descriptor should be queried.
12465
12466If the file descriptor is not connected to a terminal, an OSError
12467is thrown.
12468
12469This function will only be defined if an implementation is
12470available for this system.
12471
12472shutil.get_terminal_size is the high-level function which should
12473normally be used, os.get_terminal_size is the low-level implementation.
12474[clinic start generated code]*/
12475
12476static PyObject *
12477os_get_terminal_size_impl(PyObject *module, int fd)
12478/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012479{
12480 int columns, lines;
12481 PyObject *termsize;
12482
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012483 /* Under some conditions stdout may not be connected and
12484 * fileno(stdout) may point to an invalid file descriptor. For example
12485 * GUI apps don't have valid standard streams by default.
12486 *
12487 * If this happens, and the optional fd argument is not present,
12488 * the ioctl below will fail returning EBADF. This is what we want.
12489 */
12490
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012491#ifdef TERMSIZE_USE_IOCTL
12492 {
12493 struct winsize w;
12494 if (ioctl(fd, TIOCGWINSZ, &w))
12495 return PyErr_SetFromErrno(PyExc_OSError);
12496 columns = w.ws_col;
12497 lines = w.ws_row;
12498 }
12499#endif /* TERMSIZE_USE_IOCTL */
12500
12501#ifdef TERMSIZE_USE_CONIO
12502 {
12503 DWORD nhandle;
12504 HANDLE handle;
12505 CONSOLE_SCREEN_BUFFER_INFO csbi;
12506 switch (fd) {
12507 case 0: nhandle = STD_INPUT_HANDLE;
12508 break;
12509 case 1: nhandle = STD_OUTPUT_HANDLE;
12510 break;
12511 case 2: nhandle = STD_ERROR_HANDLE;
12512 break;
12513 default:
12514 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
12515 }
12516 handle = GetStdHandle(nhandle);
12517 if (handle == NULL)
12518 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
12519 if (handle == INVALID_HANDLE_VALUE)
12520 return PyErr_SetFromWindowsErr(0);
12521
12522 if (!GetConsoleScreenBufferInfo(handle, &csbi))
12523 return PyErr_SetFromWindowsErr(0);
12524
12525 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
12526 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
12527 }
12528#endif /* TERMSIZE_USE_CONIO */
12529
Serhiy Storchaka2b560312020-04-18 19:14:10 +030012530 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080012531 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012532 if (termsize == NULL)
12533 return NULL;
12534 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
12535 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
12536 if (PyErr_Occurred()) {
12537 Py_DECREF(termsize);
12538 return NULL;
12539 }
12540 return termsize;
12541}
12542#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
12543
Larry Hastings2f936352014-08-05 14:04:04 +100012544
12545/*[clinic input]
12546os.cpu_count
12547
Charles-François Natali80d62e62015-08-13 20:37:08 +010012548Return the number of CPUs in the system; return None if indeterminable.
12549
12550This number is not equivalent to the number of CPUs the current process can
12551use. The number of usable CPUs can be obtained with
12552``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100012553[clinic start generated code]*/
12554
Larry Hastings2f936352014-08-05 14:04:04 +100012555static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012556os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012557/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012558{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012559 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012560#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010012561 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012562#elif defined(__hpux)
12563 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
12564#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
12565 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012566#elif defined(__DragonFly__) || \
12567 defined(__OpenBSD__) || \
12568 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020012569 defined(__NetBSD__) || \
12570 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020012571 int mib[2];
12572 size_t len = sizeof(ncpu);
12573 mib[0] = CTL_HW;
12574 mib[1] = HW_NCPU;
12575 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
12576 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020012577#endif
12578 if (ncpu >= 1)
12579 return PyLong_FromLong(ncpu);
12580 else
12581 Py_RETURN_NONE;
12582}
12583
Victor Stinnerdaf45552013-08-28 00:53:59 +020012584
Larry Hastings2f936352014-08-05 14:04:04 +100012585/*[clinic input]
12586os.get_inheritable -> bool
12587
12588 fd: int
12589 /
12590
12591Get the close-on-exe flag of the specified file descriptor.
12592[clinic start generated code]*/
12593
Larry Hastings2f936352014-08-05 14:04:04 +100012594static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012595os_get_inheritable_impl(PyObject *module, int fd)
12596/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012597{
Steve Dower8fc89802015-04-12 00:26:27 -040012598 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040012599 _Py_BEGIN_SUPPRESS_IPH
12600 return_value = _Py_get_inheritable(fd);
12601 _Py_END_SUPPRESS_IPH
12602 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100012603}
12604
12605
12606/*[clinic input]
12607os.set_inheritable
12608 fd: int
12609 inheritable: int
12610 /
12611
12612Set the inheritable flag of the specified file descriptor.
12613[clinic start generated code]*/
12614
Larry Hastings2f936352014-08-05 14:04:04 +100012615static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012616os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
12617/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020012618{
Steve Dower8fc89802015-04-12 00:26:27 -040012619 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012620
Steve Dower8fc89802015-04-12 00:26:27 -040012621 _Py_BEGIN_SUPPRESS_IPH
12622 result = _Py_set_inheritable(fd, inheritable, NULL);
12623 _Py_END_SUPPRESS_IPH
12624 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020012625 return NULL;
12626 Py_RETURN_NONE;
12627}
12628
12629
12630#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100012631/*[clinic input]
12632os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070012633 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012634 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020012635
Larry Hastings2f936352014-08-05 14:04:04 +100012636Get the close-on-exe flag of the specified file descriptor.
12637[clinic start generated code]*/
12638
Larry Hastings2f936352014-08-05 14:04:04 +100012639static int
Benjamin Petersonca470632016-09-06 13:47:26 -070012640os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070012641/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012642{
12643 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012644
12645 if (!GetHandleInformation((HANDLE)handle, &flags)) {
12646 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100012647 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012648 }
12649
Larry Hastings2f936352014-08-05 14:04:04 +100012650 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012651}
12652
Victor Stinnerdaf45552013-08-28 00:53:59 +020012653
Larry Hastings2f936352014-08-05 14:04:04 +100012654/*[clinic input]
12655os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070012656 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100012657 inheritable: bool
12658 /
12659
12660Set the inheritable flag of the specified handle.
12661[clinic start generated code]*/
12662
Larry Hastings2f936352014-08-05 14:04:04 +100012663static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070012664os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040012665 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070012666/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012667{
12668 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020012669 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
12670 PyErr_SetFromWindowsErr(0);
12671 return NULL;
12672 }
12673 Py_RETURN_NONE;
12674}
Larry Hastings2f936352014-08-05 14:04:04 +100012675#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012676
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012677#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012678/*[clinic input]
12679os.get_blocking -> bool
12680 fd: int
12681 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012682
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012683Get the blocking mode of the file descriptor.
12684
12685Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
12686[clinic start generated code]*/
12687
12688static int
12689os_get_blocking_impl(PyObject *module, int fd)
12690/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012691{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012692 int blocking;
12693
Steve Dower8fc89802015-04-12 00:26:27 -040012694 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012695 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040012696 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012697 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012698}
12699
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012700/*[clinic input]
12701os.set_blocking
12702 fd: int
12703 blocking: bool(accept={int})
12704 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012705
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012706Set the blocking mode of the specified file descriptor.
12707
12708Set the O_NONBLOCK flag if blocking is False,
12709clear the O_NONBLOCK flag otherwise.
12710[clinic start generated code]*/
12711
12712static PyObject *
12713os_set_blocking_impl(PyObject *module, int fd, int blocking)
12714/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012715{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030012716 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012717
Steve Dower8fc89802015-04-12 00:26:27 -040012718 _Py_BEGIN_SUPPRESS_IPH
12719 result = _Py_set_blocking(fd, blocking);
12720 _Py_END_SUPPRESS_IPH
12721 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012722 return NULL;
12723 Py_RETURN_NONE;
12724}
12725#endif /* !MS_WINDOWS */
12726
12727
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012728/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080012729class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012730[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080012731/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012732
12733typedef struct {
12734 PyObject_HEAD
12735 PyObject *name;
12736 PyObject *path;
12737 PyObject *stat;
12738 PyObject *lstat;
12739#ifdef MS_WINDOWS
12740 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010012741 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010012742 int got_file_index;
12743#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010012744#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012745 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012746#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012747 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012748 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010012749#endif
12750} DirEntry;
12751
Eddie Elizondob3966632019-11-05 07:16:14 -080012752static PyObject *
12753_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
12754{
12755 PyErr_Format(PyExc_TypeError,
12756 "cannot create '%.100s' instances", _PyType_Name(type));
12757 return NULL;
12758}
12759
Victor Stinner6036e442015-03-08 01:58:04 +010012760static void
12761DirEntry_dealloc(DirEntry *entry)
12762{
Eddie Elizondob3966632019-11-05 07:16:14 -080012763 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010012764 Py_XDECREF(entry->name);
12765 Py_XDECREF(entry->path);
12766 Py_XDECREF(entry->stat);
12767 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080012768 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
12769 free_func(entry);
12770 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010012771}
12772
12773/* Forward reference */
12774static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012775DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
12776 int follow_symlinks, unsigned short mode_bits);
Victor Stinner6036e442015-03-08 01:58:04 +010012777
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012778/*[clinic input]
12779os.DirEntry.is_symlink -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020012780 defining_class: defining_class
12781 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012782
12783Return True if the entry is a symbolic link; cached per entry.
12784[clinic start generated code]*/
12785
Victor Stinner6036e442015-03-08 01:58:04 +010012786static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012787os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
12788/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012789{
12790#ifdef MS_WINDOWS
12791 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010012792#elif defined(HAVE_DIRENT_D_TYPE)
12793 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012794 if (self->d_type != DT_UNKNOWN)
12795 return self->d_type == DT_LNK;
12796 else
Victor Stinner97f33c32020-05-14 18:05:58 +020012797 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010012798#else
12799 /* POSIX without d_type */
Victor Stinner97f33c32020-05-14 18:05:58 +020012800 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010012801#endif
12802}
12803
12804static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012805DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
Victor Stinner6036e442015-03-08 01:58:04 +010012806{
12807 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012808 STRUCT_STAT st;
12809 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010012810
12811#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012812 if (!PyUnicode_FSDecoder(self->path, &ub))
12813 return NULL;
12814 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012815#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012816 if (!PyUnicode_FSConverter(self->path, &ub))
12817 return NULL;
12818 const char *path = PyBytes_AS_STRING(ub);
12819 if (self->dir_fd != DEFAULT_DIR_FD) {
12820#ifdef HAVE_FSTATAT
12821 result = fstatat(self->dir_fd, path, &st,
12822 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
12823#else
12824 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
12825 return NULL;
12826#endif /* HAVE_FSTATAT */
12827 }
12828 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012829#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012830 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012831 if (follow_symlinks)
12832 result = STAT(path, &st);
12833 else
12834 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012835 }
12836 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010012837
12838 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030012839 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012840
Victor Stinner97f33c32020-05-14 18:05:58 +020012841 return _pystat_fromstructstat(module, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010012842}
12843
12844static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012845DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
Victor Stinner6036e442015-03-08 01:58:04 +010012846{
12847 if (!self->lstat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020012848 PyObject *module = PyType_GetModule(defining_class);
Victor Stinner6036e442015-03-08 01:58:04 +010012849#ifdef MS_WINDOWS
Victor Stinner97f33c32020-05-14 18:05:58 +020012850 self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010012851#else /* POSIX */
Victor Stinner97f33c32020-05-14 18:05:58 +020012852 self->lstat = DirEntry_fetch_stat(module, self, 0);
Victor Stinner6036e442015-03-08 01:58:04 +010012853#endif
12854 }
12855 Py_XINCREF(self->lstat);
12856 return self->lstat;
12857}
12858
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012859/*[clinic input]
12860os.DirEntry.stat
Victor Stinner97f33c32020-05-14 18:05:58 +020012861 defining_class: defining_class
12862 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012863 *
12864 follow_symlinks: bool = True
12865
12866Return stat_result object for the entry; cached per entry.
12867[clinic start generated code]*/
12868
Victor Stinner6036e442015-03-08 01:58:04 +010012869static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020012870os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
12871 int follow_symlinks)
12872/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012873{
Victor Stinner97f33c32020-05-14 18:05:58 +020012874 if (!follow_symlinks) {
12875 return DirEntry_get_lstat(defining_class, self);
12876 }
Victor Stinner6036e442015-03-08 01:58:04 +010012877
12878 if (!self->stat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020012879 int result = os_DirEntry_is_symlink_impl(self, defining_class);
12880 if (result == -1) {
Victor Stinner6036e442015-03-08 01:58:04 +010012881 return NULL;
Victor Stinner97f33c32020-05-14 18:05:58 +020012882 }
12883 if (result) {
12884 PyObject *module = PyType_GetModule(defining_class);
12885 self->stat = DirEntry_fetch_stat(module, self, 1);
12886 }
12887 else {
12888 self->stat = DirEntry_get_lstat(defining_class, self);
12889 }
Victor Stinner6036e442015-03-08 01:58:04 +010012890 }
12891
12892 Py_XINCREF(self->stat);
12893 return self->stat;
12894}
12895
Victor Stinner6036e442015-03-08 01:58:04 +010012896/* Set exception and return -1 on error, 0 for False, 1 for True */
12897static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012898DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
12899 int follow_symlinks, unsigned short mode_bits)
Victor Stinner6036e442015-03-08 01:58:04 +010012900{
12901 PyObject *stat = NULL;
12902 PyObject *st_mode = NULL;
12903 long mode;
12904 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010012905#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012906 int is_symlink;
12907 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010012908#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012909#ifdef MS_WINDOWS
12910 unsigned long dir_bits;
12911#endif
12912
12913#ifdef MS_WINDOWS
12914 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
12915 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010012916#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012917 is_symlink = self->d_type == DT_LNK;
12918 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
12919#endif
12920
Victor Stinner35a97c02015-03-08 02:59:09 +010012921#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012922 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010012923#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020012924 stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010012925 if (!stat) {
12926 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
12927 /* If file doesn't exist (anymore), then return False
12928 (i.e., say it's not a file/directory) */
12929 PyErr_Clear();
12930 return 0;
12931 }
12932 goto error;
12933 }
Victor Stinner97f33c32020-05-14 18:05:58 +020012934 _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
12935 st_mode = PyObject_GetAttr(stat, state->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010012936 if (!st_mode)
12937 goto error;
12938
12939 mode = PyLong_AsLong(st_mode);
12940 if (mode == -1 && PyErr_Occurred())
12941 goto error;
12942 Py_CLEAR(st_mode);
12943 Py_CLEAR(stat);
12944 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010012945#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010012946 }
12947 else if (is_symlink) {
12948 assert(mode_bits != S_IFLNK);
12949 result = 0;
12950 }
12951 else {
12952 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
12953#ifdef MS_WINDOWS
12954 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
12955 if (mode_bits == S_IFDIR)
12956 result = dir_bits != 0;
12957 else
12958 result = dir_bits == 0;
12959#else /* POSIX */
12960 if (mode_bits == S_IFDIR)
12961 result = self->d_type == DT_DIR;
12962 else
12963 result = self->d_type == DT_REG;
12964#endif
12965 }
Victor Stinner35a97c02015-03-08 02:59:09 +010012966#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012967
12968 return result;
12969
12970error:
12971 Py_XDECREF(st_mode);
12972 Py_XDECREF(stat);
12973 return -1;
12974}
12975
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012976/*[clinic input]
12977os.DirEntry.is_dir -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020012978 defining_class: defining_class
12979 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012980 *
12981 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010012982
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012983Return True if the entry is a directory; cached per entry.
12984[clinic start generated code]*/
12985
12986static int
Victor Stinner97f33c32020-05-14 18:05:58 +020012987os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
12988 int follow_symlinks)
12989/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012990{
Victor Stinner97f33c32020-05-14 18:05:58 +020012991 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010012992}
12993
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012994/*[clinic input]
12995os.DirEntry.is_file -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020012996 defining_class: defining_class
12997 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012998 *
12999 follow_symlinks: bool = True
13000
13001Return True if the entry is a file; cached per entry.
13002[clinic start generated code]*/
13003
13004static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013005os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
13006 int follow_symlinks)
13007/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013008{
Victor Stinner97f33c32020-05-14 18:05:58 +020013009 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010013010}
13011
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013012/*[clinic input]
13013os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010013014
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013015Return inode of the entry; cached per entry.
13016[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013017
13018static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013019os_DirEntry_inode_impl(DirEntry *self)
13020/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013021{
13022#ifdef MS_WINDOWS
13023 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013024 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013025 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013026 STRUCT_STAT stat;
13027 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010013028
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013029 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010013030 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013031 path = PyUnicode_AsUnicode(unicode);
13032 result = LSTAT(path, &stat);
13033 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010013034
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013035 if (result != 0)
13036 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013037
13038 self->win32_file_index = stat.st_ino;
13039 self->got_file_index = 1;
13040 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013041 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13042 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013043#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013044 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13045 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013046#endif
13047}
13048
13049static PyObject *
13050DirEntry_repr(DirEntry *self)
13051{
13052 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13053}
13054
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013055/*[clinic input]
13056os.DirEntry.__fspath__
13057
13058Returns the path for the entry.
13059[clinic start generated code]*/
13060
Brett Cannon96881cd2016-06-10 14:37:21 -070013061static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013062os_DirEntry___fspath___impl(DirEntry *self)
13063/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013064{
13065 Py_INCREF(self->path);
13066 return self->path;
13067}
13068
Victor Stinner6036e442015-03-08 01:58:04 +010013069static PyMemberDef DirEntry_members[] = {
13070 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13071 "the entry's base filename, relative to scandir() \"path\" argument"},
13072 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13073 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13074 {NULL}
13075};
13076
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013077#include "clinic/posixmodule.c.h"
13078
Victor Stinner6036e442015-03-08 01:58:04 +010013079static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013080 OS_DIRENTRY_IS_DIR_METHODDEF
13081 OS_DIRENTRY_IS_FILE_METHODDEF
13082 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13083 OS_DIRENTRY_STAT_METHODDEF
13084 OS_DIRENTRY_INODE_METHODDEF
13085 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013086 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13087 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013088 {NULL}
13089};
13090
Eddie Elizondob3966632019-11-05 07:16:14 -080013091static PyType_Slot DirEntryType_slots[] = {
13092 {Py_tp_new, _disabled_new},
13093 {Py_tp_dealloc, DirEntry_dealloc},
13094 {Py_tp_repr, DirEntry_repr},
13095 {Py_tp_methods, DirEntry_methods},
13096 {Py_tp_members, DirEntry_members},
13097 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013098};
13099
Eddie Elizondob3966632019-11-05 07:16:14 -080013100static PyType_Spec DirEntryType_spec = {
13101 MODNAME ".DirEntry",
13102 sizeof(DirEntry),
13103 0,
13104 Py_TPFLAGS_DEFAULT,
13105 DirEntryType_slots
13106};
13107
13108
Victor Stinner6036e442015-03-08 01:58:04 +010013109#ifdef MS_WINDOWS
13110
13111static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013112join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013113{
13114 Py_ssize_t path_len;
13115 Py_ssize_t size;
13116 wchar_t *result;
13117 wchar_t ch;
13118
13119 if (!path_wide) { /* Default arg: "." */
13120 path_wide = L".";
13121 path_len = 1;
13122 }
13123 else {
13124 path_len = wcslen(path_wide);
13125 }
13126
13127 /* The +1's are for the path separator and the NUL */
13128 size = path_len + 1 + wcslen(filename) + 1;
13129 result = PyMem_New(wchar_t, size);
13130 if (!result) {
13131 PyErr_NoMemory();
13132 return NULL;
13133 }
13134 wcscpy(result, path_wide);
13135 if (path_len > 0) {
13136 ch = result[path_len - 1];
13137 if (ch != SEP && ch != ALTSEP && ch != L':')
13138 result[path_len++] = SEP;
13139 wcscpy(result + path_len, filename);
13140 }
13141 return result;
13142}
13143
13144static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013145DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013146{
13147 DirEntry *entry;
13148 BY_HANDLE_FILE_INFORMATION file_info;
13149 ULONG reparse_tag;
13150 wchar_t *joined_path;
13151
Victor Stinner1c2fa782020-05-10 11:05:29 +020013152 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013153 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013154 if (!entry)
13155 return NULL;
13156 entry->name = NULL;
13157 entry->path = NULL;
13158 entry->stat = NULL;
13159 entry->lstat = NULL;
13160 entry->got_file_index = 0;
13161
13162 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13163 if (!entry->name)
13164 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013165 if (path->narrow) {
13166 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13167 if (!entry->name)
13168 goto error;
13169 }
Victor Stinner6036e442015-03-08 01:58:04 +010013170
13171 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13172 if (!joined_path)
13173 goto error;
13174
13175 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13176 PyMem_Free(joined_path);
13177 if (!entry->path)
13178 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013179 if (path->narrow) {
13180 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13181 if (!entry->path)
13182 goto error;
13183 }
Victor Stinner6036e442015-03-08 01:58:04 +010013184
Steve Dowercc16be82016-09-08 10:35:16 -070013185 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013186 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13187
13188 return (PyObject *)entry;
13189
13190error:
13191 Py_DECREF(entry);
13192 return NULL;
13193}
13194
13195#else /* POSIX */
13196
13197static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013198join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013199{
13200 Py_ssize_t path_len;
13201 Py_ssize_t size;
13202 char *result;
13203
13204 if (!path_narrow) { /* Default arg: "." */
13205 path_narrow = ".";
13206 path_len = 1;
13207 }
13208 else {
13209 path_len = strlen(path_narrow);
13210 }
13211
13212 if (filename_len == -1)
13213 filename_len = strlen(filename);
13214
13215 /* The +1's are for the path separator and the NUL */
13216 size = path_len + 1 + filename_len + 1;
13217 result = PyMem_New(char, size);
13218 if (!result) {
13219 PyErr_NoMemory();
13220 return NULL;
13221 }
13222 strcpy(result, path_narrow);
13223 if (path_len > 0 && result[path_len - 1] != '/')
13224 result[path_len++] = '/';
13225 strcpy(result + path_len, filename);
13226 return result;
13227}
13228
13229static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013230DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13231 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013232#ifdef HAVE_DIRENT_D_TYPE
13233 , unsigned char d_type
13234#endif
13235 )
Victor Stinner6036e442015-03-08 01:58:04 +010013236{
13237 DirEntry *entry;
13238 char *joined_path;
13239
Victor Stinner1c2fa782020-05-10 11:05:29 +020013240 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013241 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013242 if (!entry)
13243 return NULL;
13244 entry->name = NULL;
13245 entry->path = NULL;
13246 entry->stat = NULL;
13247 entry->lstat = NULL;
13248
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013249 if (path->fd != -1) {
13250 entry->dir_fd = path->fd;
13251 joined_path = NULL;
13252 }
13253 else {
13254 entry->dir_fd = DEFAULT_DIR_FD;
13255 joined_path = join_path_filename(path->narrow, name, name_len);
13256 if (!joined_path)
13257 goto error;
13258 }
Victor Stinner6036e442015-03-08 01:58:04 +010013259
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013260 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013261 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013262 if (joined_path)
13263 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013264 }
13265 else {
13266 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013267 if (joined_path)
13268 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013269 }
13270 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013271 if (!entry->name)
13272 goto error;
13273
13274 if (path->fd != -1) {
13275 entry->path = entry->name;
13276 Py_INCREF(entry->path);
13277 }
13278 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013279 goto error;
13280
Victor Stinner35a97c02015-03-08 02:59:09 +010013281#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013282 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013283#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013284 entry->d_ino = d_ino;
13285
13286 return (PyObject *)entry;
13287
13288error:
13289 Py_XDECREF(entry);
13290 return NULL;
13291}
13292
13293#endif
13294
13295
13296typedef struct {
13297 PyObject_HEAD
13298 path_t path;
13299#ifdef MS_WINDOWS
13300 HANDLE handle;
13301 WIN32_FIND_DATAW file_data;
13302 int first_time;
13303#else /* POSIX */
13304 DIR *dirp;
13305#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013306#ifdef HAVE_FDOPENDIR
13307 int fd;
13308#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013309} ScandirIterator;
13310
13311#ifdef MS_WINDOWS
13312
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013313static int
13314ScandirIterator_is_closed(ScandirIterator *iterator)
13315{
13316 return iterator->handle == INVALID_HANDLE_VALUE;
13317}
13318
Victor Stinner6036e442015-03-08 01:58:04 +010013319static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013320ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013321{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013322 HANDLE handle = iterator->handle;
13323
13324 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013325 return;
13326
Victor Stinner6036e442015-03-08 01:58:04 +010013327 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013328 Py_BEGIN_ALLOW_THREADS
13329 FindClose(handle);
13330 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013331}
13332
13333static PyObject *
13334ScandirIterator_iternext(ScandirIterator *iterator)
13335{
13336 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13337 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013338 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013339
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013340 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013341 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013342 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013343
13344 while (1) {
13345 if (!iterator->first_time) {
13346 Py_BEGIN_ALLOW_THREADS
13347 success = FindNextFileW(iterator->handle, file_data);
13348 Py_END_ALLOW_THREADS
13349 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013350 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013351 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013352 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013353 break;
13354 }
13355 }
13356 iterator->first_time = 0;
13357
13358 /* Skip over . and .. */
13359 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020013360 wcscmp(file_data->cFileName, L"..") != 0)
13361 {
13362 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13363 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013364 if (!entry)
13365 break;
13366 return entry;
13367 }
Victor Stinner6036e442015-03-08 01:58:04 +010013368
13369 /* Loop till we get a non-dot directory or finish iterating */
13370 }
13371
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013372 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013373 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013374 return NULL;
13375}
13376
13377#else /* POSIX */
13378
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013379static int
13380ScandirIterator_is_closed(ScandirIterator *iterator)
13381{
13382 return !iterator->dirp;
13383}
13384
Victor Stinner6036e442015-03-08 01:58:04 +010013385static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013386ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013387{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013388 DIR *dirp = iterator->dirp;
13389
13390 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013391 return;
13392
Victor Stinner6036e442015-03-08 01:58:04 +010013393 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013394 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013395#ifdef HAVE_FDOPENDIR
13396 if (iterator->path.fd != -1)
13397 rewinddir(dirp);
13398#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013399 closedir(dirp);
13400 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013401 return;
13402}
13403
13404static PyObject *
13405ScandirIterator_iternext(ScandirIterator *iterator)
13406{
13407 struct dirent *direntp;
13408 Py_ssize_t name_len;
13409 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013410 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013411
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013412 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013413 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013414 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013415
13416 while (1) {
13417 errno = 0;
13418 Py_BEGIN_ALLOW_THREADS
13419 direntp = readdir(iterator->dirp);
13420 Py_END_ALLOW_THREADS
13421
13422 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013423 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013424 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013425 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013426 break;
13427 }
13428
13429 /* Skip over . and .. */
13430 name_len = NAMLEN(direntp);
13431 is_dot = direntp->d_name[0] == '.' &&
13432 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
13433 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020013434 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13435 entry = DirEntry_from_posix_info(module,
13436 &iterator->path, direntp->d_name,
13437 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013438#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020013439 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010013440#endif
13441 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013442 if (!entry)
13443 break;
13444 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013445 }
13446
13447 /* Loop till we get a non-dot directory or finish iterating */
13448 }
13449
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013450 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013451 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013452 return NULL;
13453}
13454
13455#endif
13456
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013457static PyObject *
13458ScandirIterator_close(ScandirIterator *self, PyObject *args)
13459{
13460 ScandirIterator_closedir(self);
13461 Py_RETURN_NONE;
13462}
13463
13464static PyObject *
13465ScandirIterator_enter(PyObject *self, PyObject *args)
13466{
13467 Py_INCREF(self);
13468 return self;
13469}
13470
13471static PyObject *
13472ScandirIterator_exit(ScandirIterator *self, PyObject *args)
13473{
13474 ScandirIterator_closedir(self);
13475 Py_RETURN_NONE;
13476}
13477
Victor Stinner6036e442015-03-08 01:58:04 +010013478static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010013479ScandirIterator_finalize(ScandirIterator *iterator)
13480{
13481 PyObject *error_type, *error_value, *error_traceback;
13482
13483 /* Save the current exception, if any. */
13484 PyErr_Fetch(&error_type, &error_value, &error_traceback);
13485
13486 if (!ScandirIterator_is_closed(iterator)) {
13487 ScandirIterator_closedir(iterator);
13488
13489 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
13490 "unclosed scandir iterator %R", iterator)) {
13491 /* Spurious errors can appear at shutdown */
13492 if (PyErr_ExceptionMatches(PyExc_Warning)) {
13493 PyErr_WriteUnraisable((PyObject *) iterator);
13494 }
13495 }
13496 }
13497
Victor Stinner7bfa4092016-03-23 00:43:54 +010013498 path_cleanup(&iterator->path);
13499
13500 /* Restore the saved exception. */
13501 PyErr_Restore(error_type, error_value, error_traceback);
13502}
13503
13504static void
Victor Stinner6036e442015-03-08 01:58:04 +010013505ScandirIterator_dealloc(ScandirIterator *iterator)
13506{
Eddie Elizondob3966632019-11-05 07:16:14 -080013507 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010013508 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
13509 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013510
Eddie Elizondob3966632019-11-05 07:16:14 -080013511 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13512 free_func(iterator);
13513 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013514}
13515
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013516static PyMethodDef ScandirIterator_methods[] = {
13517 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
13518 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
13519 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
13520 {NULL}
13521};
13522
Eddie Elizondob3966632019-11-05 07:16:14 -080013523static PyType_Slot ScandirIteratorType_slots[] = {
13524 {Py_tp_new, _disabled_new},
13525 {Py_tp_dealloc, ScandirIterator_dealloc},
13526 {Py_tp_finalize, ScandirIterator_finalize},
13527 {Py_tp_iter, PyObject_SelfIter},
13528 {Py_tp_iternext, ScandirIterator_iternext},
13529 {Py_tp_methods, ScandirIterator_methods},
13530 {0, 0},
13531};
13532
13533static PyType_Spec ScandirIteratorType_spec = {
13534 MODNAME ".ScandirIterator",
13535 sizeof(ScandirIterator),
13536 0,
Victor Stinner97f33c32020-05-14 18:05:58 +020013537 // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
13538 // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
Eddie Elizondob3966632019-11-05 07:16:14 -080013539 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
13540 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010013541};
13542
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013543/*[clinic input]
13544os.scandir
13545
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013546 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013547
13548Return an iterator of DirEntry objects for given path.
13549
BNMetricsb9427072018-11-02 15:20:19 +000013550path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013551is bytes, the names of yielded DirEntry objects will also be bytes; in
13552all other circumstances they will be str.
13553
13554If path is None, uses the path='.'.
13555[clinic start generated code]*/
13556
Victor Stinner6036e442015-03-08 01:58:04 +010013557static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013558os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000013559/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013560{
13561 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010013562#ifdef MS_WINDOWS
13563 wchar_t *path_strW;
13564#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013565 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013566#ifdef HAVE_FDOPENDIR
13567 int fd = -1;
13568#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013569#endif
13570
Steve Dower60419a72019-06-24 08:42:54 -070013571 if (PySys_Audit("os.scandir", "O",
13572 path->object ? path->object : Py_None) < 0) {
13573 return NULL;
13574 }
13575
Hai Shif707d942020-03-16 21:15:01 +080013576 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013577 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010013578 if (!iterator)
13579 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013580
13581#ifdef MS_WINDOWS
13582 iterator->handle = INVALID_HANDLE_VALUE;
13583#else
13584 iterator->dirp = NULL;
13585#endif
13586
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013587 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020013588 /* Move the ownership to iterator->path */
13589 path->object = NULL;
13590 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013591
13592#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010013593 iterator->first_time = 1;
13594
13595 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
13596 if (!path_strW)
13597 goto error;
13598
13599 Py_BEGIN_ALLOW_THREADS
13600 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
13601 Py_END_ALLOW_THREADS
13602
13603 PyMem_Free(path_strW);
13604
13605 if (iterator->handle == INVALID_HANDLE_VALUE) {
13606 path_error(&iterator->path);
13607 goto error;
13608 }
13609#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013610 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013611#ifdef HAVE_FDOPENDIR
13612 if (path->fd != -1) {
13613 /* closedir() closes the FD, so we duplicate it */
13614 fd = _Py_dup(path->fd);
13615 if (fd == -1)
13616 goto error;
13617
13618 Py_BEGIN_ALLOW_THREADS
13619 iterator->dirp = fdopendir(fd);
13620 Py_END_ALLOW_THREADS
13621 }
13622 else
13623#endif
13624 {
13625 if (iterator->path.narrow)
13626 path_str = iterator->path.narrow;
13627 else
13628 path_str = ".";
13629
13630 Py_BEGIN_ALLOW_THREADS
13631 iterator->dirp = opendir(path_str);
13632 Py_END_ALLOW_THREADS
13633 }
Victor Stinner6036e442015-03-08 01:58:04 +010013634
13635 if (!iterator->dirp) {
13636 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013637#ifdef HAVE_FDOPENDIR
13638 if (fd != -1) {
13639 Py_BEGIN_ALLOW_THREADS
13640 close(fd);
13641 Py_END_ALLOW_THREADS
13642 }
13643#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013644 goto error;
13645 }
13646#endif
13647
13648 return (PyObject *)iterator;
13649
13650error:
13651 Py_DECREF(iterator);
13652 return NULL;
13653}
13654
Ethan Furman410ef8e2016-06-04 12:06:26 -070013655/*
13656 Return the file system path representation of the object.
13657
13658 If the object is str or bytes, then allow it to pass through with
13659 an incremented refcount. If the object defines __fspath__(), then
13660 return the result of that method. All other types raise a TypeError.
13661*/
13662PyObject *
13663PyOS_FSPath(PyObject *path)
13664{
Brett Cannon3f9183b2016-08-26 14:44:48 -070013665 /* For error message reasons, this function is manually inlined in
13666 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070013667 PyObject *func = NULL;
13668 PyObject *path_repr = NULL;
13669
13670 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
13671 Py_INCREF(path);
13672 return path;
13673 }
13674
13675 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
13676 if (NULL == func) {
13677 return PyErr_Format(PyExc_TypeError,
13678 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013679 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080013680 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070013681 }
13682
Victor Stinnerf17c3de2016-12-06 18:46:19 +010013683 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070013684 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070013685 if (NULL == path_repr) {
13686 return NULL;
13687 }
13688
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013689 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
13690 PyErr_Format(PyExc_TypeError,
13691 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080013692 "not %.200s", _PyType_Name(Py_TYPE(path)),
13693 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070013694 Py_DECREF(path_repr);
13695 return NULL;
13696 }
13697
Ethan Furman410ef8e2016-06-04 12:06:26 -070013698 return path_repr;
13699}
13700
13701/*[clinic input]
13702os.fspath
13703
13704 path: object
13705
13706Return the file system path representation of the object.
13707
Brett Cannonb4f43e92016-06-09 14:32:08 -070013708If the object is str or bytes, then allow it to pass through as-is. If the
13709object defines __fspath__(), then return the result of that method. All other
13710types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070013711[clinic start generated code]*/
13712
13713static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013714os_fspath_impl(PyObject *module, PyObject *path)
13715/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070013716{
13717 return PyOS_FSPath(path);
13718}
Victor Stinner6036e442015-03-08 01:58:04 +010013719
Victor Stinner9b1f4742016-09-06 16:18:52 -070013720#ifdef HAVE_GETRANDOM_SYSCALL
13721/*[clinic input]
13722os.getrandom
13723
13724 size: Py_ssize_t
13725 flags: int=0
13726
13727Obtain a series of random bytes.
13728[clinic start generated code]*/
13729
13730static PyObject *
13731os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
13732/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
13733{
Victor Stinner9b1f4742016-09-06 16:18:52 -070013734 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013735 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013736
13737 if (size < 0) {
13738 errno = EINVAL;
13739 return posix_error();
13740 }
13741
Victor Stinnerec2319c2016-09-20 23:00:59 +020013742 bytes = PyBytes_FromStringAndSize(NULL, size);
13743 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013744 PyErr_NoMemory();
13745 return NULL;
13746 }
13747
13748 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013749 n = syscall(SYS_getrandom,
13750 PyBytes_AS_STRING(bytes),
13751 PyBytes_GET_SIZE(bytes),
13752 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070013753 if (n < 0 && errno == EINTR) {
13754 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020013755 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013756 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020013757
13758 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070013759 continue;
13760 }
13761 break;
13762 }
13763
13764 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070013765 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020013766 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013767 }
13768
Victor Stinnerec2319c2016-09-20 23:00:59 +020013769 if (n != size) {
13770 _PyBytes_Resize(&bytes, n);
13771 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070013772
13773 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020013774
13775error:
13776 Py_DECREF(bytes);
13777 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070013778}
13779#endif /* HAVE_GETRANDOM_SYSCALL */
13780
Steve Dower2438cdf2019-03-29 16:37:16 -070013781#ifdef MS_WINDOWS
13782/* bpo-36085: Helper functions for managing DLL search directories
13783 * on win32
13784 */
13785
13786typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
13787typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
13788
13789/*[clinic input]
13790os._add_dll_directory
13791
13792 path: path_t
13793
13794Add a path to the DLL search path.
13795
13796This search path is used when resolving dependencies for imported
13797extension modules (the module itself is resolved through sys.path),
13798and also by ctypes.
13799
13800Returns an opaque value that may be passed to os.remove_dll_directory
13801to remove this directory from the search path.
13802[clinic start generated code]*/
13803
13804static PyObject *
13805os__add_dll_directory_impl(PyObject *module, path_t *path)
13806/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
13807{
13808 HMODULE hKernel32;
13809 PAddDllDirectory AddDllDirectory;
13810 DLL_DIRECTORY_COOKIE cookie = 0;
13811 DWORD err = 0;
13812
Saiyang Gou7514f4f2020-02-12 23:47:42 -080013813 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
13814 return NULL;
13815 }
13816
Steve Dower2438cdf2019-03-29 16:37:16 -070013817 /* For Windows 7, we have to load this. As this will be a fairly
13818 infrequent operation, just do it each time. Kernel32 is always
13819 loaded. */
13820 Py_BEGIN_ALLOW_THREADS
13821 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13822 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
13823 hKernel32, "AddDllDirectory")) ||
13824 !(cookie = (*AddDllDirectory)(path->wide))) {
13825 err = GetLastError();
13826 }
13827 Py_END_ALLOW_THREADS
13828
13829 if (err) {
13830 return win32_error_object_err("add_dll_directory",
13831 path->object, err);
13832 }
13833
13834 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
13835}
13836
13837/*[clinic input]
13838os._remove_dll_directory
13839
13840 cookie: object
13841
13842Removes a path from the DLL search path.
13843
13844The parameter is an opaque value that was returned from
13845os.add_dll_directory. You can only remove directories that you added
13846yourself.
13847[clinic start generated code]*/
13848
13849static PyObject *
13850os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
13851/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
13852{
13853 HMODULE hKernel32;
13854 PRemoveDllDirectory RemoveDllDirectory;
13855 DLL_DIRECTORY_COOKIE cookieValue;
13856 DWORD err = 0;
13857
13858 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
13859 PyErr_SetString(PyExc_TypeError,
13860 "Provided cookie was not returned from os.add_dll_directory");
13861 return NULL;
13862 }
13863
13864 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
13865 cookie, "DLL directory cookie");
13866
13867 /* For Windows 7, we have to load this. As this will be a fairly
13868 infrequent operation, just do it each time. Kernel32 is always
13869 loaded. */
13870 Py_BEGIN_ALLOW_THREADS
13871 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
13872 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
13873 hKernel32, "RemoveDllDirectory")) ||
13874 !(*RemoveDllDirectory)(cookieValue)) {
13875 err = GetLastError();
13876 }
13877 Py_END_ALLOW_THREADS
13878
13879 if (err) {
13880 return win32_error_object_err("remove_dll_directory",
13881 NULL, err);
13882 }
13883
13884 if (PyCapsule_SetName(cookie, NULL)) {
13885 return NULL;
13886 }
13887
13888 Py_RETURN_NONE;
13889}
13890
13891#endif
Larry Hastings31826802013-10-19 00:09:25 -070013892
Victor Stinner65a796e2020-04-01 18:49:29 +020013893
13894/* Only check if WIFEXITED is available: expect that it comes
13895 with WEXITSTATUS, WIFSIGNALED, etc.
13896
13897 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
13898 subprocess can safely call it during late Python finalization without
13899 risking that used os attributes were set to None by _PyImport_Cleanup(). */
13900#if defined(WIFEXITED) || defined(MS_WINDOWS)
13901/*[clinic input]
13902os.waitstatus_to_exitcode
13903
Victor Stinner9bee32b2020-04-22 16:30:35 +020013904 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020013905
13906Convert a wait status to an exit code.
13907
13908On Unix:
13909
13910* If WIFEXITED(status) is true, return WEXITSTATUS(status).
13911* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
13912* Otherwise, raise a ValueError.
13913
13914On Windows, return status shifted right by 8 bits.
13915
13916On Unix, if the process is being traced or if waitpid() was called with
13917WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
13918This function must not be called if WIFSTOPPED(status) is true.
13919[clinic start generated code]*/
13920
13921static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020013922os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
13923/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020013924{
Victor Stinner9bee32b2020-04-22 16:30:35 +020013925 if (PyFloat_Check(status_obj)) {
13926 PyErr_SetString(PyExc_TypeError,
13927 "integer argument expected, got float" );
13928 return NULL;
13929 }
Victor Stinner65a796e2020-04-01 18:49:29 +020013930#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020013931 int status = _PyLong_AsInt(status_obj);
13932 if (status == -1 && PyErr_Occurred()) {
13933 return NULL;
13934 }
13935
Victor Stinner65a796e2020-04-01 18:49:29 +020013936 WAIT_TYPE wait_status;
13937 WAIT_STATUS_INT(wait_status) = status;
13938 int exitcode;
13939 if (WIFEXITED(wait_status)) {
13940 exitcode = WEXITSTATUS(wait_status);
13941 /* Sanity check to provide warranty on the function behavior.
13942 It should not occur in practice */
13943 if (exitcode < 0) {
13944 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
13945 return NULL;
13946 }
13947 }
13948 else if (WIFSIGNALED(wait_status)) {
13949 int signum = WTERMSIG(wait_status);
13950 /* Sanity check to provide warranty on the function behavior.
13951 It should not occurs in practice */
13952 if (signum <= 0) {
13953 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
13954 return NULL;
13955 }
13956 exitcode = -signum;
13957 } else if (WIFSTOPPED(wait_status)) {
13958 /* Status only received if the process is being traced
13959 or if waitpid() was called with WUNTRACED option. */
13960 int signum = WSTOPSIG(wait_status);
13961 PyErr_Format(PyExc_ValueError,
13962 "process stopped by delivery of signal %i",
13963 signum);
13964 return NULL;
13965 }
13966 else {
13967 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
13968 return NULL;
13969 }
13970 return PyLong_FromLong(exitcode);
13971#else
13972 /* Windows implementation: see os.waitpid() implementation
13973 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020013974 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
13975 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
13976 return NULL;
13977 }
13978
13979 unsigned long long exitcode = (status >> 8);
13980 /* ExitProcess() accepts an UINT type:
13981 reject exit code which doesn't fit in an UINT */
13982 if (exitcode > UINT_MAX) {
13983 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
13984 return NULL;
13985 }
13986 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020013987#endif
13988}
13989#endif
13990
13991
Fred Drake5ab8eaf1999-12-09 21:13:07 +000013992static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070013993
13994 OS_STAT_METHODDEF
13995 OS_ACCESS_METHODDEF
13996 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100013997 OS_CHDIR_METHODDEF
13998 OS_CHFLAGS_METHODDEF
13999 OS_CHMOD_METHODDEF
14000 OS_FCHMOD_METHODDEF
14001 OS_LCHMOD_METHODDEF
14002 OS_CHOWN_METHODDEF
14003 OS_FCHOWN_METHODDEF
14004 OS_LCHOWN_METHODDEF
14005 OS_LCHFLAGS_METHODDEF
14006 OS_CHROOT_METHODDEF
14007 OS_CTERMID_METHODDEF
14008 OS_GETCWD_METHODDEF
14009 OS_GETCWDB_METHODDEF
14010 OS_LINK_METHODDEF
14011 OS_LISTDIR_METHODDEF
14012 OS_LSTAT_METHODDEF
14013 OS_MKDIR_METHODDEF
14014 OS_NICE_METHODDEF
14015 OS_GETPRIORITY_METHODDEF
14016 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014017 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030014018 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014019 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010014020 OS_COPY_FILE_RANGE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014021 OS_RENAME_METHODDEF
14022 OS_REPLACE_METHODDEF
14023 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014024 OS_SYMLINK_METHODDEF
14025 OS_SYSTEM_METHODDEF
14026 OS_UMASK_METHODDEF
14027 OS_UNAME_METHODDEF
14028 OS_UNLINK_METHODDEF
14029 OS_REMOVE_METHODDEF
14030 OS_UTIME_METHODDEF
14031 OS_TIMES_METHODDEF
14032 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014033 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014034 OS_EXECV_METHODDEF
14035 OS_EXECVE_METHODDEF
14036 OS_SPAWNV_METHODDEF
14037 OS_SPAWNVE_METHODDEF
14038 OS_FORK1_METHODDEF
14039 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014040 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014041 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14042 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14043 OS_SCHED_GETPARAM_METHODDEF
14044 OS_SCHED_GETSCHEDULER_METHODDEF
14045 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14046 OS_SCHED_SETPARAM_METHODDEF
14047 OS_SCHED_SETSCHEDULER_METHODDEF
14048 OS_SCHED_YIELD_METHODDEF
14049 OS_SCHED_SETAFFINITY_METHODDEF
14050 OS_SCHED_GETAFFINITY_METHODDEF
14051 OS_OPENPTY_METHODDEF
14052 OS_FORKPTY_METHODDEF
14053 OS_GETEGID_METHODDEF
14054 OS_GETEUID_METHODDEF
14055 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014056 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014057 OS_GETGROUPS_METHODDEF
14058 OS_GETPID_METHODDEF
14059 OS_GETPGRP_METHODDEF
14060 OS_GETPPID_METHODDEF
14061 OS_GETUID_METHODDEF
14062 OS_GETLOGIN_METHODDEF
14063 OS_KILL_METHODDEF
14064 OS_KILLPG_METHODDEF
14065 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014066 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014067 OS_SETUID_METHODDEF
14068 OS_SETEUID_METHODDEF
14069 OS_SETREUID_METHODDEF
14070 OS_SETGID_METHODDEF
14071 OS_SETEGID_METHODDEF
14072 OS_SETREGID_METHODDEF
14073 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014074 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014075 OS_GETPGID_METHODDEF
14076 OS_SETPGRP_METHODDEF
14077 OS_WAIT_METHODDEF
14078 OS_WAIT3_METHODDEF
14079 OS_WAIT4_METHODDEF
14080 OS_WAITID_METHODDEF
14081 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014082 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014083 OS_GETSID_METHODDEF
14084 OS_SETSID_METHODDEF
14085 OS_SETPGID_METHODDEF
14086 OS_TCGETPGRP_METHODDEF
14087 OS_TCSETPGRP_METHODDEF
14088 OS_OPEN_METHODDEF
14089 OS_CLOSE_METHODDEF
14090 OS_CLOSERANGE_METHODDEF
14091 OS_DEVICE_ENCODING_METHODDEF
14092 OS_DUP_METHODDEF
14093 OS_DUP2_METHODDEF
14094 OS_LOCKF_METHODDEF
14095 OS_LSEEK_METHODDEF
14096 OS_READ_METHODDEF
14097 OS_READV_METHODDEF
14098 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014099 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014100 OS_WRITE_METHODDEF
14101 OS_WRITEV_METHODDEF
14102 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014103 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014104 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014105 OS_FSTAT_METHODDEF
14106 OS_ISATTY_METHODDEF
14107 OS_PIPE_METHODDEF
14108 OS_PIPE2_METHODDEF
14109 OS_MKFIFO_METHODDEF
14110 OS_MKNOD_METHODDEF
14111 OS_MAJOR_METHODDEF
14112 OS_MINOR_METHODDEF
14113 OS_MAKEDEV_METHODDEF
14114 OS_FTRUNCATE_METHODDEF
14115 OS_TRUNCATE_METHODDEF
14116 OS_POSIX_FALLOCATE_METHODDEF
14117 OS_POSIX_FADVISE_METHODDEF
14118 OS_PUTENV_METHODDEF
14119 OS_UNSETENV_METHODDEF
14120 OS_STRERROR_METHODDEF
14121 OS_FCHDIR_METHODDEF
14122 OS_FSYNC_METHODDEF
14123 OS_SYNC_METHODDEF
14124 OS_FDATASYNC_METHODDEF
14125 OS_WCOREDUMP_METHODDEF
14126 OS_WIFCONTINUED_METHODDEF
14127 OS_WIFSTOPPED_METHODDEF
14128 OS_WIFSIGNALED_METHODDEF
14129 OS_WIFEXITED_METHODDEF
14130 OS_WEXITSTATUS_METHODDEF
14131 OS_WTERMSIG_METHODDEF
14132 OS_WSTOPSIG_METHODDEF
14133 OS_FSTATVFS_METHODDEF
14134 OS_STATVFS_METHODDEF
14135 OS_CONFSTR_METHODDEF
14136 OS_SYSCONF_METHODDEF
14137 OS_FPATHCONF_METHODDEF
14138 OS_PATHCONF_METHODDEF
14139 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014140 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014141 OS__GETDISKUSAGE_METHODDEF
14142 OS__GETFINALPATHNAME_METHODDEF
14143 OS__GETVOLUMEPATHNAME_METHODDEF
14144 OS_GETLOADAVG_METHODDEF
14145 OS_URANDOM_METHODDEF
14146 OS_SETRESUID_METHODDEF
14147 OS_SETRESGID_METHODDEF
14148 OS_GETRESUID_METHODDEF
14149 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014150
Larry Hastings2f936352014-08-05 14:04:04 +100014151 OS_GETXATTR_METHODDEF
14152 OS_SETXATTR_METHODDEF
14153 OS_REMOVEXATTR_METHODDEF
14154 OS_LISTXATTR_METHODDEF
14155
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014156 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014157 OS_CPU_COUNT_METHODDEF
14158 OS_GET_INHERITABLE_METHODDEF
14159 OS_SET_INHERITABLE_METHODDEF
14160 OS_GET_HANDLE_INHERITABLE_METHODDEF
14161 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014162 OS_GET_BLOCKING_METHODDEF
14163 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014164 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014165 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014166 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014167 OS_MEMFD_CREATE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014168 OS__ADD_DLL_DIRECTORY_METHODDEF
14169 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014170 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014171 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014172};
14173
Barry Warsaw4a342091996-12-19 23:50:02 +000014174static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014175all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014176{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014177#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014178 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014179#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014180#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014181 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014182#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014183#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014184 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014185#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014186#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014187 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014188#endif
Fred Drakec9680921999-12-13 16:37:25 +000014189#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014190 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014191#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014192#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014193 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014194#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014195#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014196 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014197#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014198#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014199 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014200#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014201#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014202 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014203#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014204#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014205 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014206#endif
14207#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014208 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014209#endif
14210#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014211 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014212#endif
14213#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014214 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014215#endif
14216#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014217 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014218#endif
14219#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014220 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014221#endif
14222#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014223 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014224#endif
14225#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014226 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014227#endif
14228#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014229 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014230#endif
14231#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014232 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014233#endif
14234#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014235 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014236#endif
14237#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014238 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014239#endif
14240#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014241 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014242#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014243#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014244 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014245#endif
14246#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014247 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014248#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014249#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014250 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014251#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014252#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014253 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014254#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014255#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014256#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014257 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014258#endif
14259#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014260 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014261#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014262#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014263#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014264 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014265#endif
14266#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014267 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014268#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014269#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014270 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014271#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014272#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014273 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014274#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014275#ifdef O_TMPFILE
14276 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14277#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014278#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014279 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014280#endif
14281#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014282 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014283#endif
14284#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014285 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014286#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014287#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014288 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014289#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014290#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014291 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014292#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014293
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014294
Jesus Cea94363612012-06-22 18:32:07 +020014295#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014296 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014297#endif
14298#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014299 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014300#endif
14301
Tim Peters5aa91602002-01-30 05:46:57 +000014302/* MS Windows */
14303#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014304 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014305 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014306#endif
14307#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000014308 /* Optimize for short life (keep in memory). */
14309 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014310 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014311#endif
14312#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000014313 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014314 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014315#endif
14316#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000014317 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014318 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014319#endif
14320#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014321 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014322 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014323#endif
14324
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014325/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014326#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014327 /* Send a SIGIO signal whenever input or output
14328 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014329 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014330#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014331#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014332 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014333 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014334#endif
14335#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000014336 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014337 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014338#endif
14339#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000014340 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014341 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014342#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014343#ifdef O_NOLINKS
14344 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014345 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014346#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014347#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014348 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014349 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014350#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000014351
Victor Stinner8c62be82010-05-06 00:08:46 +000014352 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014353#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014354 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014355#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014356#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014357 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014358#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014359#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014360 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014361#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014362#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014363 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014364#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014365#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014366 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014367#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014368#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014369 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014370#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014371#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014372 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014373#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014374#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014375 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014376#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014377#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014378 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014379#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014380#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014381 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014382#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014383#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014384 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014385#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014386#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014387 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014388#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014389#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014390 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014391#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014392#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014393 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014394#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014395#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014396 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014397#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014398#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014399 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014400#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014401#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014402 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014403#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014404
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000014405 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014406#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014407 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014408#endif /* ST_RDONLY */
14409#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014410 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000014411#endif /* ST_NOSUID */
14412
doko@ubuntu.comca616a22013-12-08 15:23:07 +010014413 /* GNU extensions */
14414#ifdef ST_NODEV
14415 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
14416#endif /* ST_NODEV */
14417#ifdef ST_NOEXEC
14418 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
14419#endif /* ST_NOEXEC */
14420#ifdef ST_SYNCHRONOUS
14421 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
14422#endif /* ST_SYNCHRONOUS */
14423#ifdef ST_MANDLOCK
14424 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
14425#endif /* ST_MANDLOCK */
14426#ifdef ST_WRITE
14427 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
14428#endif /* ST_WRITE */
14429#ifdef ST_APPEND
14430 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
14431#endif /* ST_APPEND */
14432#ifdef ST_NOATIME
14433 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
14434#endif /* ST_NOATIME */
14435#ifdef ST_NODIRATIME
14436 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
14437#endif /* ST_NODIRATIME */
14438#ifdef ST_RELATIME
14439 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
14440#endif /* ST_RELATIME */
14441
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014442 /* FreeBSD sendfile() constants */
14443#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014444 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014445#endif
14446#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014447 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014448#endif
14449#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014450 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000014451#endif
14452
Ross Lagerwall7807c352011-03-17 20:20:30 +020014453 /* constants for posix_fadvise */
14454#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014455 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014456#endif
14457#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014458 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014459#endif
14460#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014461 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014462#endif
14463#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014464 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014465#endif
14466#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014467 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014468#endif
14469#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014470 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014471#endif
14472
14473 /* constants for waitid */
14474#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014475 if (PyModule_AddIntMacro(m, P_PID)) return -1;
14476 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
14477 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080014478#ifdef P_PIDFD
14479 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
14480#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014481#endif
14482#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014483 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014484#endif
14485#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014486 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014487#endif
14488#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014489 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014490#endif
14491#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014492 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014493#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014494#ifdef CLD_KILLED
14495 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
14496#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014497#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014498 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014499#endif
14500#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014501 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014502#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090014503#ifdef CLD_STOPPED
14504 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
14505#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020014506#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014507 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014508#endif
14509
14510 /* constants for lockf */
14511#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014512 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014513#endif
14514#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014515 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014516#endif
14517#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014518 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014519#endif
14520#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014521 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014522#endif
14523
Pablo Galindo4defba32018-01-27 16:16:37 +000014524#ifdef RWF_DSYNC
14525 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
14526#endif
14527#ifdef RWF_HIPRI
14528 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
14529#endif
14530#ifdef RWF_SYNC
14531 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
14532#endif
14533#ifdef RWF_NOWAIT
14534 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
14535#endif
14536
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014537/* constants for posix_spawn */
14538#ifdef HAVE_POSIX_SPAWN
14539 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
14540 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
14541 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
14542#endif
14543
pxinwrf2d7ac72019-05-21 18:46:37 +080014544#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014545 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
14546 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014547 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080014548#endif
14549#ifdef HAVE_SPAWNV
14550 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014551 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000014552#endif
14553
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014554#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014555#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014556 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014557#endif
14558#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014559 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014560#endif
14561#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014562 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070014563#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014564#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080014565 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014566#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014567#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014568 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014569#endif
14570#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014571 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014572#endif
14573#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014574 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014575#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014576#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014577 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014578#endif
14579#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014580 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014581#endif
14582#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014583 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014584#endif
14585#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014586 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020014587#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014588#endif
14589
Benjamin Peterson9428d532011-09-14 11:45:52 -040014590#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014591 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
14592 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
14593 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040014594#endif
14595
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014596#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014597 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014598#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014599#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014600 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014601#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014602#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014603 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014604#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014605#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014606 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014607#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014608#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014609 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014610#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014611#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014612 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014613#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030014614#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014615 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020014616#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010014617#if HAVE_DECL_RTLD_MEMBER
14618 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
14619#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020014620
Victor Stinner9b1f4742016-09-06 16:18:52 -070014621#ifdef HAVE_GETRANDOM_SYSCALL
14622 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
14623 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
14624#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014625#ifdef HAVE_MEMFD_CREATE
14626 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
14627 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
14628#ifdef MFD_HUGETLB
14629 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014630#endif
14631#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014632 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014633#endif
14634#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014635 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014636#endif
14637#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014638 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014639#endif
14640#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014641 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014642#endif
14643#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014644 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014645#endif
14646#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014647 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014648#endif
14649#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014650 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014651#endif
14652#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014653 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014654#endif
14655#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014656 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014657#endif
14658#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014659 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014660#endif
14661#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014662 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014663#endif
14664#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014665 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014666#endif
14667#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014668 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060014669#endif
14670#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014671 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
14672#endif
14673#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070014674
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014675#if defined(__APPLE__)
14676 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
14677#endif
14678
Steve Dower2438cdf2019-03-29 16:37:16 -070014679#ifdef MS_WINDOWS
14680 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
14681 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
14682 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
14683 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
14684 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
14685#endif
14686
Victor Stinner8c62be82010-05-06 00:08:46 +000014687 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000014688}
14689
14690
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020014691static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070014692
14693#ifdef HAVE_FACCESSAT
14694 "HAVE_FACCESSAT",
14695#endif
14696
14697#ifdef HAVE_FCHDIR
14698 "HAVE_FCHDIR",
14699#endif
14700
14701#ifdef HAVE_FCHMOD
14702 "HAVE_FCHMOD",
14703#endif
14704
14705#ifdef HAVE_FCHMODAT
14706 "HAVE_FCHMODAT",
14707#endif
14708
14709#ifdef HAVE_FCHOWN
14710 "HAVE_FCHOWN",
14711#endif
14712
Larry Hastings00964ed2013-08-12 13:49:30 -040014713#ifdef HAVE_FCHOWNAT
14714 "HAVE_FCHOWNAT",
14715#endif
14716
Larry Hastings9cf065c2012-06-22 16:30:09 -070014717#ifdef HAVE_FEXECVE
14718 "HAVE_FEXECVE",
14719#endif
14720
14721#ifdef HAVE_FDOPENDIR
14722 "HAVE_FDOPENDIR",
14723#endif
14724
Georg Brandl306336b2012-06-24 12:55:33 +020014725#ifdef HAVE_FPATHCONF
14726 "HAVE_FPATHCONF",
14727#endif
14728
Larry Hastings9cf065c2012-06-22 16:30:09 -070014729#ifdef HAVE_FSTATAT
14730 "HAVE_FSTATAT",
14731#endif
14732
14733#ifdef HAVE_FSTATVFS
14734 "HAVE_FSTATVFS",
14735#endif
14736
Steve Dowerfe0a41a2015-03-20 19:50:46 -070014737#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020014738 "HAVE_FTRUNCATE",
14739#endif
14740
Larry Hastings9cf065c2012-06-22 16:30:09 -070014741#ifdef HAVE_FUTIMENS
14742 "HAVE_FUTIMENS",
14743#endif
14744
14745#ifdef HAVE_FUTIMES
14746 "HAVE_FUTIMES",
14747#endif
14748
14749#ifdef HAVE_FUTIMESAT
14750 "HAVE_FUTIMESAT",
14751#endif
14752
14753#ifdef HAVE_LINKAT
14754 "HAVE_LINKAT",
14755#endif
14756
14757#ifdef HAVE_LCHFLAGS
14758 "HAVE_LCHFLAGS",
14759#endif
14760
14761#ifdef HAVE_LCHMOD
14762 "HAVE_LCHMOD",
14763#endif
14764
14765#ifdef HAVE_LCHOWN
14766 "HAVE_LCHOWN",
14767#endif
14768
14769#ifdef HAVE_LSTAT
14770 "HAVE_LSTAT",
14771#endif
14772
14773#ifdef HAVE_LUTIMES
14774 "HAVE_LUTIMES",
14775#endif
14776
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014777#ifdef HAVE_MEMFD_CREATE
14778 "HAVE_MEMFD_CREATE",
14779#endif
14780
Larry Hastings9cf065c2012-06-22 16:30:09 -070014781#ifdef HAVE_MKDIRAT
14782 "HAVE_MKDIRAT",
14783#endif
14784
14785#ifdef HAVE_MKFIFOAT
14786 "HAVE_MKFIFOAT",
14787#endif
14788
14789#ifdef HAVE_MKNODAT
14790 "HAVE_MKNODAT",
14791#endif
14792
14793#ifdef HAVE_OPENAT
14794 "HAVE_OPENAT",
14795#endif
14796
14797#ifdef HAVE_READLINKAT
14798 "HAVE_READLINKAT",
14799#endif
14800
14801#ifdef HAVE_RENAMEAT
14802 "HAVE_RENAMEAT",
14803#endif
14804
14805#ifdef HAVE_SYMLINKAT
14806 "HAVE_SYMLINKAT",
14807#endif
14808
14809#ifdef HAVE_UNLINKAT
14810 "HAVE_UNLINKAT",
14811#endif
14812
14813#ifdef HAVE_UTIMENSAT
14814 "HAVE_UTIMENSAT",
14815#endif
14816
14817#ifdef MS_WINDOWS
14818 "MS_WINDOWS",
14819#endif
14820
14821 NULL
14822};
14823
14824
Victor Stinner1c2fa782020-05-10 11:05:29 +020014825static int
14826posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000014827{
Victor Stinner97f33c32020-05-14 18:05:58 +020014828 _posixstate *state = get_posix_state(m);
Tim Peters5aa91602002-01-30 05:46:57 +000014829
Victor Stinner8c62be82010-05-06 00:08:46 +000014830 /* Initialize environ dictionary */
Victor Stinner97f33c32020-05-14 18:05:58 +020014831 PyObject *v = convertenviron();
Victor Stinner8c62be82010-05-06 00:08:46 +000014832 Py_XINCREF(v);
14833 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014834 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014835 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000014836
Victor Stinner8c62be82010-05-06 00:08:46 +000014837 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014838 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014839
Victor Stinner8c62be82010-05-06 00:08:46 +000014840 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020014841 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000014842
Victor Stinner8c62be82010-05-06 00:08:46 +000014843 Py_INCREF(PyExc_OSError);
14844 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000014845
Ross Lagerwall7807c352011-03-17 20:20:30 +020014846#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080014847 waitid_result_desc.name = MODNAME ".waitid_result";
14848 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
14849 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014850 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014851 }
14852 Py_INCREF(WaitidResultType);
14853 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014854 state->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020014855#endif
14856
Eddie Elizondob3966632019-11-05 07:16:14 -080014857 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
14858 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
14859 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
14860 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
14861 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
14862 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014863 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014864 }
14865 Py_INCREF(StatResultType);
14866 PyModule_AddObject(m, "stat_result", StatResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014867 state->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014868 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
14869 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014870
Eddie Elizondob3966632019-11-05 07:16:14 -080014871 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
14872 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
14873 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014874 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014875 }
14876 Py_INCREF(StatVFSResultType);
14877 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014878 state->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014879#ifdef NEED_TICKS_PER_SECOND
14880# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080014881 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014882# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080014883 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014884# else
Eddie Elizondob3966632019-11-05 07:16:14 -080014885 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000014886# endif
14887#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050014888
William Orr81574b82018-10-01 22:19:56 -070014889#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080014890 sched_param_desc.name = MODNAME ".sched_param";
14891 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
14892 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014893 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014894 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014895 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080014896 PyModule_AddObject(m, "sched_param", SchedParamType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014897 state->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014898 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050014899#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000014900
Eddie Elizondob3966632019-11-05 07:16:14 -080014901 /* initialize TerminalSize_info */
14902 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
14903 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014904 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014905 }
14906 Py_INCREF(TerminalSizeType);
14907 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014908 state->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014909
14910 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020014911 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080014912 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014913 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014914 }
Victor Stinner97f33c32020-05-14 18:05:58 +020014915 state->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014916
Victor Stinner1c2fa782020-05-10 11:05:29 +020014917 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080014918 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014919 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014920 }
14921 Py_INCREF(DirEntryType);
14922 PyModule_AddObject(m, "DirEntry", DirEntryType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014923 state->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014924
Larry Hastings605a62d2012-06-24 04:33:36 -070014925 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080014926 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014927 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014928 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014929 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014930 Py_INCREF(TimesResultType);
14931 PyModule_AddObject(m, "times_result", TimesResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014932 state->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014933
Eddie Elizondob3966632019-11-05 07:16:14 -080014934 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014935 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014936 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014937 }
Eddie Elizondob3966632019-11-05 07:16:14 -080014938 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080014939 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020014940 state->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070014941
Thomas Wouters477c8d52006-05-27 19:21:47 +000014942#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000014943 /*
14944 * Step 2 of weak-linking support on Mac OS X.
14945 *
14946 * The code below removes functions that are not available on the
14947 * currently active platform.
14948 *
14949 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070014950 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000014951 * OSX 10.4.
14952 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000014953#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014954 if (fstatvfs == NULL) {
14955 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014956 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014957 }
14958 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014959#endif /* HAVE_FSTATVFS */
14960
14961#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000014962 if (statvfs == NULL) {
14963 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014964 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014965 }
14966 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014967#endif /* HAVE_STATVFS */
14968
14969# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000014970 if (lchown == NULL) {
14971 if (PyObject_DelAttrString(m, "lchown") == -1) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014972 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000014973 }
14974 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000014975#endif /* HAVE_LCHOWN */
14976
14977
14978#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010014979
Victor Stinner97f33c32020-05-14 18:05:58 +020014980 if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014981 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014982#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +020014983 state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
14984 if (state->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014985 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080014986#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020014987 state->st_mode = PyUnicode_InternFromString("st_mode");
14988 if (state->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020014989 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070014990
Larry Hastings9cf065c2012-06-22 16:30:09 -070014991 /* suppress "function not used" warnings */
14992 {
14993 int ignored;
14994 fd_specified("", -1);
14995 follow_symlinks_specified("", 1);
14996 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
14997 dir_fd_converter(Py_None, &ignored);
14998 dir_fd_unavailable(Py_None, &ignored);
14999 }
15000
15001 /*
15002 * provide list of locally available functions
15003 * so os.py can populate support_* lists
15004 */
Victor Stinner97f33c32020-05-14 18:05:58 +020015005 PyObject *list = PyList_New(0);
15006 if (!list) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015007 return -1;
Victor Stinner97f33c32020-05-14 18:05:58 +020015008 }
15009 for (const char * const *trace = have_functions; *trace; trace++) {
Larry Hastings9cf065c2012-06-22 16:30:09 -070015010 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
15011 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015012 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015013 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015014 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015015 Py_DECREF(unicode);
15016 }
15017 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040015018
Victor Stinner1c2fa782020-05-10 11:05:29 +020015019 return 0;
15020}
15021
15022
15023static PyModuleDef_Slot posixmodile_slots[] = {
15024 {Py_mod_exec, posixmodule_exec},
15025 {0, NULL}
15026};
15027
15028static struct PyModuleDef posixmodule = {
15029 PyModuleDef_HEAD_INIT,
15030 .m_name = MODNAME,
15031 .m_doc = posix__doc__,
15032 .m_size = sizeof(_posixstate),
15033 .m_methods = posix_methods,
15034 .m_slots = posixmodile_slots,
15035 .m_traverse = _posix_traverse,
15036 .m_clear = _posix_clear,
15037 .m_free = _posix_free,
15038};
15039
15040PyMODINIT_FUNC
15041INITFUNC(void)
15042{
15043 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015044}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015045
15046#ifdef __cplusplus
15047}
15048#endif