blob: efa96531d49c1c40975bb828e0d003a030d75f5d [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 Wouters68bc4f92006-03-01 01:05:10 +000010#define PY_SSIZE_T_CLEAN
11
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000012#include "Python.h"
Kyle Evans79925792020-10-13 15:04:44 -050013#include "pycore_fileutils.h"
Victor Stinnerd5d9e812019-05-13 12:35:37 +020014#ifdef MS_WINDOWS
15 /* include <windows.h> early to avoid conflict with pycore_condvar.h:
16
17 #define WIN32_LEAN_AND_MEAN
18 #include <windows.h>
19
20 FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
21# include <windows.h>
22#endif
23
pxinwr3405e052020-08-07 13:21:52 +080024#ifdef __VXWORKS__
25# include "pycore_bitutils.h" // _Py_popcount32()
26#endif
Victor Stinner4a21e572020-04-15 02:35:41 +020027#include "pycore_ceval.h" // _PyEval_ReInitThreads()
28#include "pycore_import.h" // _PyImport_ReInitLock()
Victor Stinner26881c82020-06-02 15:51:37 +020029#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
Victor Stinner4a21e572020-04-15 02:35:41 +020030#include "pycore_pystate.h" // _PyInterpreterState_GET()
31#include "structmember.h" // PyMemberDef
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020032#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020033# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010034#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020035# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020036#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000037
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020038/* On android API level 21, 'AT_EACCESS' is not declared although
39 * HAVE_FACCESSAT is defined. */
40#ifdef __ANDROID__
Victor Stinner5eca75d2020-04-15 15:07:31 +020041# undef HAVE_FACCESSAT
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020042#endif
43
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000044#include <stdio.h> /* needed for ctermid() */
45
Ronald Oussoren41761932020-11-08 10:05:27 +010046/*
47 * A number of APIs are available on macOS from a certain macOS version.
48 * To support building with a new SDK while deploying to older versions
49 * the availability test is split into two:
50 * - HAVE_<FUNCTION>: The configure check for compile time availability
51 * - HAVE_<FUNCTION>_RUNTIME: Runtime check for availability
52 *
53 * The latter is always true when not on macOS, or when using a compiler
54 * that does not support __has_builtin (older versions of Xcode).
55 *
56 * Due to compiler restrictions there is one valid use of HAVE_<FUNCTION>_RUNTIME:
57 * if (HAVE_<FUNCTION>_RUNTIME) { ... }
58 *
59 * In mixing the test with other tests or using negations will result in compile
60 * errors.
61 */
62#if defined(__APPLE__)
63
64#if defined(__has_builtin) && __has_builtin(__builtin_available)
65# define HAVE_FSTATAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
66# define HAVE_FACCESSAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
67# define HAVE_FCHMODAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
68# define HAVE_FCHOWNAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
69# define HAVE_LINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
70# define HAVE_FDOPENDIR_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
71# define HAVE_MKDIRAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
72# define HAVE_RENAMEAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
73# define HAVE_UNLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
74# define HAVE_OPENAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
75# define HAVE_READLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
76# define HAVE_SYMLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
77# define HAVE_FUTIMENS_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
78# define HAVE_UTIMENSAT_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
79# define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
80
81# define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *)
82
83#else /* Xcode 8 or earlier */
84
85 /* __builtin_available is not present in these compilers, but
86 * some of the symbols might be weak linked (10.10 SDK or later
87 * deploying on 10.9.
88 *
89 * Fall back to the older style of availability checking for
90 * symbols introduced in macOS 10.10.
91 */
92
93# ifdef HAVE_FSTATAT
94# define HAVE_FSTATAT_RUNTIME (fstatat != NULL)
95# endif
96
97# ifdef HAVE_FACCESSAT
98# define HAVE_FACCESSAT_RUNTIME (faccessat != NULL)
99# endif
100
101# ifdef HAVE_FCHMODAT
102# define HAVE_FCHMODAT_RUNTIME (fchmodat != NULL)
103# endif
104
105# ifdef HAVE_FCHOWNAT
106# define HAVE_FCHOWNAT_RUNTIME (fchownat != NULL)
107# endif
108
109# ifdef HAVE_LINKAT
110# define HAVE_LINKAT_RUNTIME (linkat != NULL)
111# endif
112
113# ifdef HAVE_FDOPENDIR
114# define HAVE_FDOPENDIR_RUNTIME (fdopendir != NULL)
115# endif
116
117# ifdef HAVE_MKDIRAT
118# define HAVE_MKDIRAT_RUNTIME (mkdirat != NULL)
119# endif
120
121# ifdef HAVE_RENAMEAT
122# define HAVE_RENAMEAT_RUNTIME (renameat != NULL)
123# endif
124
125# ifdef HAVE_UNLINKAT
126# define HAVE_UNLINKAT_RUNTIME (unlinkat != NULL)
127# endif
128
129# ifdef HAVE_OPENAT
130# define HAVE_OPENAT_RUNTIME (openat != NULL)
131# endif
132
133# ifdef HAVE_READLINKAT
134# define HAVE_READLINKAT_RUNTIME (readlinkat != NULL)
135# endif
136
137# ifdef HAVE_SYMLINKAT
138# define HAVE_SYMLINKAT_RUNTIME (symlinkat != NULL)
139# endif
140
141#endif
142
143#ifdef HAVE_FUTIMESAT
144/* Some of the logic for weak linking depends on this assertion */
145# error "HAVE_FUTIMESAT unexpectedly defined"
146#endif
147
148#else
149# define HAVE_FSTATAT_RUNTIME 1
150# define HAVE_FACCESSAT_RUNTIME 1
151# define HAVE_FCHMODAT_RUNTIME 1
152# define HAVE_FCHOWNAT_RUNTIME 1
153# define HAVE_LINKAT_RUNTIME 1
154# define HAVE_FDOPENDIR_RUNTIME 1
155# define HAVE_MKDIRAT_RUNTIME 1
156# define HAVE_RENAMEAT_RUNTIME 1
157# define HAVE_UNLINKAT_RUNTIME 1
158# define HAVE_OPENAT_RUNTIME 1
159# define HAVE_READLINKAT_RUNTIME 1
160# define HAVE_SYMLINKAT_RUNTIME 1
161# define HAVE_FUTIMENS_RUNTIME 1
162# define HAVE_UTIMENSAT_RUNTIME 1
163# define HAVE_PWRITEV_RUNTIME 1
164#endif
165
166
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000167#ifdef __cplusplus
168extern "C" {
169#endif
170
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000171PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000172"This module provides access to operating system functionality that is\n\
173standardized by the C Standard and the POSIX standard (a thinly\n\
174disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000175corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176
Martin v. Löwis0073f2e2002-11-21 23:52:35 +0000177
Ross Lagerwall4d076da2011-03-18 06:56:53 +0200178#ifdef HAVE_SYS_UIO_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200179# include <sys/uio.h>
Ross Lagerwall4d076da2011-03-18 06:56:53 +0200180#endif
181
Christian Heimes75b96182017-09-05 15:53:09 +0200182#ifdef HAVE_SYS_SYSMACROS_H
183/* GNU C Library: major(), minor(), makedev() */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200184# include <sys/sysmacros.h>
Christian Heimes75b96182017-09-05 15:53:09 +0200185#endif
186
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000187#ifdef HAVE_SYS_TYPES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200188# include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000189#endif /* HAVE_SYS_TYPES_H */
190
191#ifdef HAVE_SYS_STAT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200192# include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000193#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000194
Guido van Rossum36bc6801995-06-14 22:54:23 +0000195#ifdef HAVE_SYS_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200196# include <sys/wait.h> // WNOHANG
Guido van Rossum36bc6801995-06-14 22:54:23 +0000197#endif
Benjamin Peterson5c0c3252019-11-05 21:58:31 -0800198#ifdef HAVE_LINUX_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200199# include <linux/wait.h> // P_PIDFD
Benjamin Peterson5c0c3252019-11-05 21:58:31 -0800200#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000202#ifdef HAVE_SIGNAL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200203# include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000204#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +0000205
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#ifdef HAVE_FCNTL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200207# include <fcntl.h>
208#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000210#ifdef HAVE_GRP_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200211# include <grp.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000212#endif
213
Barry Warsaw5676bd12003-01-07 20:57:09 +0000214#ifdef HAVE_SYSEXITS_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200215# include <sysexits.h>
216#endif
Barry Warsaw5676bd12003-01-07 20:57:09 +0000217
Anthony Baxter8a560de2004-10-13 15:30:56 +0000218#ifdef HAVE_SYS_LOADAVG_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200219# include <sys/loadavg.h>
Anthony Baxter8a560de2004-10-13 15:30:56 +0000220#endif
221
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000222#ifdef HAVE_SYS_SENDFILE_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200223# include <sys/sendfile.h>
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000224#endif
225
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200226#if defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200227# include <copyfile.h>
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200228#endif
229
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500230#ifdef HAVE_SCHED_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200231# include <sched.h>
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500232#endif
233
Pablo Galindoaac4d032019-05-31 19:39:47 +0100234#ifdef HAVE_COPY_FILE_RANGE
Victor Stinner5eca75d2020-04-15 15:07:31 +0200235# include <unistd.h>
Pablo Galindoaac4d032019-05-31 19:39:47 +0100236#endif
237
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500238#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200239# undef HAVE_SCHED_SETAFFINITY
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500240#endif
241
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200242#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200243# define USE_XATTRS
Benjamin Peterson9428d532011-09-14 11:45:52 -0400244#endif
245
246#ifdef USE_XATTRS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200247# include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400248#endif
249
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000250#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200251# ifdef HAVE_SYS_SOCKET_H
252# include <sys/socket.h>
253# endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000254#endif
255
Victor Stinner8b905bd2011-10-25 13:34:04 +0200256#ifdef HAVE_DLFCN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200257# include <dlfcn.h>
Victor Stinner8b905bd2011-10-25 13:34:04 +0200258#endif
259
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200260#ifdef __hpux
Victor Stinner5eca75d2020-04-15 15:07:31 +0200261# include <sys/mpctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200262#endif
263
264#if defined(__DragonFly__) || \
265 defined(__OpenBSD__) || \
266 defined(__FreeBSD__) || \
267 defined(__NetBSD__) || \
268 defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200269# include <sys/sysctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200270#endif
271
Victor Stinner9b1f4742016-09-06 16:18:52 -0700272#ifdef HAVE_LINUX_RANDOM_H
273# include <linux/random.h>
274#endif
275#ifdef HAVE_GETRANDOM_SYSCALL
276# include <sys/syscall.h>
277#endif
278
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100279#if defined(MS_WINDOWS)
280# define TERMSIZE_USE_CONIO
281#elif defined(HAVE_SYS_IOCTL_H)
282# include <sys/ioctl.h>
283# if defined(HAVE_TERMIOS_H)
284# include <termios.h>
285# endif
286# if defined(TIOCGWINSZ)
287# define TERMSIZE_USE_IOCTL
288# endif
289#endif /* MS_WINDOWS */
290
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000291/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000292/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000293#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200294# define HAVE_OPENDIR 1
295# define HAVE_SYSTEM 1
296# include <process.h>
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000297#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200298# ifdef _MSC_VER
299 /* Microsoft compiler */
300# define HAVE_GETPPID 1
301# define HAVE_GETLOGIN 1
302# define HAVE_SPAWNV 1
303# define HAVE_EXECV 1
304# define HAVE_WSPAWNV 1
305# define HAVE_WEXECV 1
306# define HAVE_PIPE 1
307# define HAVE_SYSTEM 1
308# define HAVE_CWAIT 1
309# define HAVE_FSYNC 1
310# define fsync _commit
311# else
312 /* Unix functions that the configure script doesn't check for */
313# ifndef __VXWORKS__
314# define HAVE_EXECV 1
315# define HAVE_FORK 1
316# if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
317# define HAVE_FORK1 1
318# endif
319# endif
320# define HAVE_GETEGID 1
321# define HAVE_GETEUID 1
322# define HAVE_GETGID 1
323# define HAVE_GETPPID 1
324# define HAVE_GETUID 1
325# define HAVE_KILL 1
326# define HAVE_OPENDIR 1
327# define HAVE_PIPE 1
328# define HAVE_SYSTEM 1
329# define HAVE_WAIT 1
330# define HAVE_TTYNAME 1
331# endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000332#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000333
Eddie Elizondob3966632019-11-05 07:16:14 -0800334_Py_IDENTIFIER(__fspath__);
Victor Stinnera2f7c002012-02-08 03:36:25 +0100335
Larry Hastings61272b72014-01-07 12:41:53 -0800336/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000337# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800338module os
Larry Hastings61272b72014-01-07 12:41:53 -0800339[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000340/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100341
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000342#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000343
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000344#if defined(__sgi)&&_COMPILER_VERSION>=700
345/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
346 (default) */
347extern char *ctermid_r(char *);
348#endif
349
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000350#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351
pxinwrf2d7ac72019-05-21 18:46:37 +0800352#if defined(__VXWORKS__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200353# include <vxCpuLib.h>
354# include <rtpLib.h>
355# include <wait.h>
356# include <taskLib.h>
357# ifndef _P_WAIT
358# define _P_WAIT 0
359# define _P_NOWAIT 1
360# define _P_NOWAITO 1
361# endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800362#endif /* __VXWORKS__ */
363
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000364#ifdef HAVE_POSIX_SPAWN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200365# include <spawn.h>
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000366#endif
367
Guido van Rossumb6775db1994-08-01 11:34:53 +0000368#ifdef HAVE_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200369# include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000370#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000371
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000372#ifdef HAVE_SYS_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200373# include <sys/utime.h>
374# define HAVE_UTIME_H /* pretend we do for the rest of this file */
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000375#endif /* HAVE_SYS_UTIME_H */
376
Guido van Rossumb6775db1994-08-01 11:34:53 +0000377#ifdef HAVE_SYS_TIMES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200378# include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000379#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000380
381#ifdef HAVE_SYS_PARAM_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200382# include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000383#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000384
385#ifdef HAVE_SYS_UTSNAME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200386# include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000387#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000388
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000389#ifdef HAVE_DIRENT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200390# include <dirent.h>
391# define NAMLEN(dirent) strlen((dirent)->d_name)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000392#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200393# if defined(__WATCOMC__) && !defined(__QNX__)
394# include <direct.h>
395# define NAMLEN(dirent) strlen((dirent)->d_name)
396# else
397# define dirent direct
398# define NAMLEN(dirent) (dirent)->d_namlen
399# endif
400# ifdef HAVE_SYS_NDIR_H
401# include <sys/ndir.h>
402# endif
403# ifdef HAVE_SYS_DIR_H
404# include <sys/dir.h>
405# endif
406# ifdef HAVE_NDIR_H
407# include <ndir.h>
408# endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000409#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000410
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000411#ifdef _MSC_VER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200412# ifdef HAVE_DIRECT_H
413# include <direct.h>
414# endif
415# ifdef HAVE_IO_H
416# include <io.h>
417# endif
418# ifdef HAVE_PROCESS_H
419# include <process.h>
420# endif
421# ifndef IO_REPARSE_TAG_SYMLINK
422# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
423# endif
424# ifndef IO_REPARSE_TAG_MOUNT_POINT
425# define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
426# endif
427# include "osdefs.h" // SEP
428# include <malloc.h>
429# include <windows.h>
430# include <shellapi.h> // ShellExecute()
431# include <lmcons.h> // UNLEN
432# define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000433#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000434
Tim Petersbc2e10e2002-03-03 23:17:02 +0000435#ifndef MAXPATHLEN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200436# if defined(PATH_MAX) && PATH_MAX > 1024
437# define MAXPATHLEN PATH_MAX
438# else
439# define MAXPATHLEN 1024
440# endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000441#endif /* MAXPATHLEN */
442
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000443#ifdef UNION_WAIT
Victor Stinner5eca75d2020-04-15 15:07:31 +0200444 /* Emulate some macros on systems that have a union instead of macros */
445# ifndef WIFEXITED
446# define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
447# endif
448# ifndef WEXITSTATUS
449# define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
450# endif
451# ifndef WTERMSIG
452# define WTERMSIG(u_wait) ((u_wait).w_termsig)
453# endif
454# define WAIT_TYPE union wait
455# define WAIT_STATUS_INT(s) (s.w_status)
456#else
457 /* !UNION_WAIT */
458# define WAIT_TYPE int
459# define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000460#endif /* UNION_WAIT */
461
Greg Wardb48bc172000-03-01 21:51:56 +0000462/* Don't use the "_r" form if we don't need it (also, won't have a
463 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200464#if defined(HAVE_CTERMID_R)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200465# define USE_CTERMID_R
Greg Wardb48bc172000-03-01 21:51:56 +0000466#endif
467
Fred Drake699f3522000-06-29 21:12:41 +0000468/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000469#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000470#undef FSTAT
471#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200472#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200473# define STAT win32_stat
474# define LSTAT win32_lstat
475# define FSTAT _Py_fstat_noraise
476# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000477#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200478# define STAT stat
479# define LSTAT lstat
480# define FSTAT fstat
481# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000482#endif
483
Tim Peters11b23062003-04-23 02:39:17 +0000484#if defined(MAJOR_IN_MKDEV)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200485# include <sys/mkdev.h>
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000486#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200487# if defined(MAJOR_IN_SYSMACROS)
488# include <sys/sysmacros.h>
489# endif
490# if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
491# include <sys/mkdev.h>
492# endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000493#endif
Fred Drake699f3522000-06-29 21:12:41 +0000494
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200495#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200496# define INITFUNC PyInit_nt
497# define MODNAME "nt"
Victor Stinner6036e442015-03-08 01:58:04 +0100498#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200499# define INITFUNC PyInit_posix
500# define MODNAME "posix"
Victor Stinner6036e442015-03-08 01:58:04 +0100501#endif
502
jcea6c51d512018-01-28 14:00:08 +0100503#if defined(__sun)
504/* Something to implement in autoconf, not present in autoconf 2.69 */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200505# define HAVE_STRUCT_STAT_ST_FSTYPE 1
jcea6c51d512018-01-28 14:00:08 +0100506#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200507
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600508/* memfd_create is either defined in sys/mman.h or sys/memfd.h
509 * linux/memfd.h defines additional flags
510 */
511#ifdef HAVE_SYS_MMAN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200512# include <sys/mman.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600513#endif
514#ifdef HAVE_SYS_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200515# include <sys/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600516#endif
517#ifdef HAVE_LINUX_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200518# include <linux/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600519#endif
520
Christian Heimescd9fed62020-11-13 19:48:52 +0100521/* eventfd() */
522#ifdef HAVE_SYS_EVENTFD_H
523# include <sys/eventfd.h>
524#endif
525
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800526#ifdef _Py_MEMORY_SANITIZER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200527# include <sanitizer/msan_interface.h>
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800528#endif
529
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200530#ifdef HAVE_FORK
531static void
532run_at_forkers(PyObject *lst, int reverse)
533{
534 Py_ssize_t i;
535 PyObject *cpy;
536
537 if (lst != NULL) {
538 assert(PyList_CheckExact(lst));
539
540 /* Use a list copy in case register_at_fork() is called from
541 * one of the callbacks.
542 */
543 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
544 if (cpy == NULL)
545 PyErr_WriteUnraisable(lst);
546 else {
547 if (reverse)
548 PyList_Reverse(cpy);
549 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
550 PyObject *func, *res;
551 func = PyList_GET_ITEM(cpy, i);
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +0200552 res = _PyObject_CallNoArg(func);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200553 if (res == NULL)
554 PyErr_WriteUnraisable(func);
555 else
556 Py_DECREF(res);
557 }
558 Py_DECREF(cpy);
559 }
560 }
561}
562
563void
564PyOS_BeforeFork(void)
565{
Victor Stinner81a7be32020-04-14 15:14:01 +0200566 run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200567
568 _PyImport_AcquireLock();
569}
570
571void
572PyOS_AfterFork_Parent(void)
573{
574 if (_PyImport_ReleaseLock() <= 0)
575 Py_FatalError("failed releasing import lock after fork");
576
Victor Stinner81a7be32020-04-14 15:14:01 +0200577 run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200578}
579
580void
581PyOS_AfterFork_Child(void)
582{
Victor Stinner26881c82020-06-02 15:51:37 +0200583 PyStatus status;
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200584 _PyRuntimeState *runtime = &_PyRuntime;
Victor Stinner26881c82020-06-02 15:51:37 +0200585
586 status = _PyGILState_Reinit(runtime);
587 if (_PyStatus_EXCEPTION(status)) {
588 goto fatal_error;
589 }
590
Victor Stinner317bab02020-06-02 18:44:54 +0200591 PyThreadState *tstate = _PyThreadState_GET();
592 _Py_EnsureTstateNotNULL(tstate);
593
594 status = _PyEval_ReInitThreads(tstate);
Victor Stinner26881c82020-06-02 15:51:37 +0200595 if (_PyStatus_EXCEPTION(status)) {
596 goto fatal_error;
597 }
598
599 status = _PyImport_ReInitLock();
600 if (_PyStatus_EXCEPTION(status)) {
601 goto fatal_error;
602 }
603
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200604 _PySignal_AfterFork();
Victor Stinner26881c82020-06-02 15:51:37 +0200605
606 status = _PyRuntimeState_ReInitThreads(runtime);
607 if (_PyStatus_EXCEPTION(status)) {
608 goto fatal_error;
609 }
610
611 status = _PyInterpreterState_DeleteExceptMain(runtime);
612 if (_PyStatus_EXCEPTION(status)) {
613 goto fatal_error;
614 }
Victor Stinner317bab02020-06-02 18:44:54 +0200615 assert(_PyThreadState_GET() == tstate);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200616
Victor Stinner317bab02020-06-02 18:44:54 +0200617 run_at_forkers(tstate->interp->after_forkers_child, 0);
Victor Stinner26881c82020-06-02 15:51:37 +0200618 return;
619
620fatal_error:
621 Py_ExitStatusException(status);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200622}
623
624static int
625register_at_forker(PyObject **lst, PyObject *func)
626{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700627 if (func == NULL) /* nothing to register? do nothing. */
628 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200629 if (*lst == NULL) {
630 *lst = PyList_New(0);
631 if (*lst == NULL)
632 return -1;
633 }
634 return PyList_Append(*lst, func);
635}
Victor Stinner87255be2020-04-07 23:11:49 +0200636#endif /* HAVE_FORK */
637
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200638
639/* Legacy wrapper */
640void
641PyOS_AfterFork(void)
642{
643#ifdef HAVE_FORK
644 PyOS_AfterFork_Child();
645#endif
646}
647
648
Victor Stinner6036e442015-03-08 01:58:04 +0100649#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200650/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700651void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
652void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200653 ULONG, struct _Py_stat_struct *);
654#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700655
Larry Hastings9cf065c2012-06-22 16:30:09 -0700656
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200657#ifndef MS_WINDOWS
658PyObject *
659_PyLong_FromUid(uid_t uid)
660{
661 if (uid == (uid_t)-1)
662 return PyLong_FromLong(-1);
663 return PyLong_FromUnsignedLong(uid);
664}
665
666PyObject *
667_PyLong_FromGid(gid_t gid)
668{
669 if (gid == (gid_t)-1)
670 return PyLong_FromLong(-1);
671 return PyLong_FromUnsignedLong(gid);
672}
673
674int
675_Py_Uid_Converter(PyObject *obj, void *p)
676{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700677 uid_t uid;
678 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200679 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200680 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700681 unsigned long uresult;
682
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300683 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684 if (index == NULL) {
685 PyErr_Format(PyExc_TypeError,
686 "uid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800687 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200688 return 0;
689 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700690
691 /*
692 * Handling uid_t is complicated for two reasons:
693 * * Although uid_t is (always?) unsigned, it still
694 * accepts -1.
695 * * We don't know its size in advance--it may be
696 * bigger than an int, or it may be smaller than
697 * a long.
698 *
699 * So a bit of defensive programming is in order.
700 * Start with interpreting the value passed
701 * in as a signed long and see if it works.
702 */
703
704 result = PyLong_AsLongAndOverflow(index, &overflow);
705
706 if (!overflow) {
707 uid = (uid_t)result;
708
709 if (result == -1) {
710 if (PyErr_Occurred())
711 goto fail;
712 /* It's a legitimate -1, we're done. */
713 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200714 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700715
716 /* Any other negative number is disallowed. */
717 if (result < 0)
718 goto underflow;
719
720 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200721 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700722 (long)uid != result)
723 goto underflow;
724 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200725 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700726
727 if (overflow < 0)
728 goto underflow;
729
730 /*
731 * Okay, the value overflowed a signed long. If it
732 * fits in an *unsigned* long, it may still be okay,
733 * as uid_t may be unsigned long on this platform.
734 */
735 uresult = PyLong_AsUnsignedLong(index);
736 if (PyErr_Occurred()) {
737 if (PyErr_ExceptionMatches(PyExc_OverflowError))
738 goto overflow;
739 goto fail;
740 }
741
742 uid = (uid_t)uresult;
743
744 /*
745 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
746 * but this value would get interpreted as (uid_t)-1 by chown
747 * and its siblings. That's not what the user meant! So we
748 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100749 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700750 */
751 if (uid == (uid_t)-1)
752 goto overflow;
753
754 /* Ensure the value wasn't truncated. */
755 if (sizeof(uid_t) < sizeof(long) &&
756 (unsigned long)uid != uresult)
757 goto overflow;
758 /* fallthrough */
759
760success:
761 Py_DECREF(index);
762 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200763 return 1;
764
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700765underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200766 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700767 "uid is less than minimum");
768 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200769
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700770overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200771 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700772 "uid is greater than maximum");
773 /* fallthrough */
774
775fail:
776 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200777 return 0;
778}
779
780int
781_Py_Gid_Converter(PyObject *obj, void *p)
782{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700783 gid_t gid;
784 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200785 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200786 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700787 unsigned long uresult;
788
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300789 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700790 if (index == NULL) {
791 PyErr_Format(PyExc_TypeError,
792 "gid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800793 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200794 return 0;
795 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700796
797 /*
798 * Handling gid_t is complicated for two reasons:
799 * * Although gid_t is (always?) unsigned, it still
800 * accepts -1.
801 * * We don't know its size in advance--it may be
802 * bigger than an int, or it may be smaller than
803 * a long.
804 *
805 * So a bit of defensive programming is in order.
806 * Start with interpreting the value passed
807 * in as a signed long and see if it works.
808 */
809
810 result = PyLong_AsLongAndOverflow(index, &overflow);
811
812 if (!overflow) {
813 gid = (gid_t)result;
814
815 if (result == -1) {
816 if (PyErr_Occurred())
817 goto fail;
818 /* It's a legitimate -1, we're done. */
819 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200820 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700821
822 /* Any other negative number is disallowed. */
823 if (result < 0) {
824 goto underflow;
825 }
826
827 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200828 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700829 (long)gid != result)
830 goto underflow;
831 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200832 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700833
834 if (overflow < 0)
835 goto underflow;
836
837 /*
838 * Okay, the value overflowed a signed long. If it
839 * fits in an *unsigned* long, it may still be okay,
840 * as gid_t may be unsigned long on this platform.
841 */
842 uresult = PyLong_AsUnsignedLong(index);
843 if (PyErr_Occurred()) {
844 if (PyErr_ExceptionMatches(PyExc_OverflowError))
845 goto overflow;
846 goto fail;
847 }
848
849 gid = (gid_t)uresult;
850
851 /*
852 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
853 * but this value would get interpreted as (gid_t)-1 by chown
854 * and its siblings. That's not what the user meant! So we
855 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100856 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700857 */
858 if (gid == (gid_t)-1)
859 goto overflow;
860
861 /* Ensure the value wasn't truncated. */
862 if (sizeof(gid_t) < sizeof(long) &&
863 (unsigned long)gid != uresult)
864 goto overflow;
865 /* fallthrough */
866
867success:
868 Py_DECREF(index);
869 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200870 return 1;
871
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700872underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200873 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700874 "gid is less than minimum");
875 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200876
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700877overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200878 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700879 "gid is greater than maximum");
880 /* fallthrough */
881
882fail:
883 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200884 return 0;
885}
886#endif /* MS_WINDOWS */
887
888
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700889#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800890
891
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200892#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
893static int
894_Py_Dev_Converter(PyObject *obj, void *p)
895{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200896 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200897 if (PyErr_Occurred())
898 return 0;
899 return 1;
900}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800901#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200902
903
Larry Hastings9cf065c2012-06-22 16:30:09 -0700904#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400905/*
906 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
907 * without the int cast, the value gets interpreted as uint (4291925331),
908 * which doesn't play nicely with all the initializer lines in this file that
909 * look like this:
910 * int dir_fd = DEFAULT_DIR_FD;
911 */
912#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700913#else
914#define DEFAULT_DIR_FD (-100)
915#endif
916
917static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300918_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200919{
920 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700921 long long_value;
922
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300923 PyObject *index = _PyNumber_Index(o);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700924 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700925 return 0;
926 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700927
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300928 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700929 long_value = PyLong_AsLongAndOverflow(index, &overflow);
930 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300931 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200932 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700934 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935 return 0;
936 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200937 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700938 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700939 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700940 return 0;
941 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700942
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943 *p = (int)long_value;
944 return 1;
945}
946
947static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200948dir_fd_converter(PyObject *o, void *p)
949{
950 if (o == Py_None) {
951 *(int *)p = DEFAULT_DIR_FD;
952 return 1;
953 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300954 else if (PyIndex_Check(o)) {
955 return _fd_converter(o, (int *)p);
956 }
957 else {
958 PyErr_Format(PyExc_TypeError,
959 "argument should be integer or None, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800960 _PyType_Name(Py_TYPE(o)));
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300961 return 0;
962 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700963}
964
Eddie Elizondob3966632019-11-05 07:16:14 -0800965typedef struct {
966 PyObject *billion;
Eddie Elizondob3966632019-11-05 07:16:14 -0800967 PyObject *DirEntryType;
968 PyObject *ScandirIteratorType;
969#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
970 PyObject *SchedParamType;
971#endif
972 PyObject *StatResultType;
973 PyObject *StatVFSResultType;
974 PyObject *TerminalSizeType;
975 PyObject *TimesResultType;
976 PyObject *UnameResultType;
977#if defined(HAVE_WAITID) && !defined(__APPLE__)
978 PyObject *WaitidResultType;
979#endif
980#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
981 PyObject *struct_rusage;
982#endif
983 PyObject *st_mode;
984} _posixstate;
985
Eddie Elizondob3966632019-11-05 07:16:14 -0800986
Hai Shif707d942020-03-16 21:15:01 +0800987static inline _posixstate*
988get_posix_state(PyObject *module)
989{
990 void *state = PyModule_GetState(module);
991 assert(state != NULL);
992 return (_posixstate *)state;
993}
994
Larry Hastings9cf065c2012-06-22 16:30:09 -0700995/*
996 * A PyArg_ParseTuple "converter" function
997 * that handles filesystem paths in the manner
998 * preferred by the os module.
999 *
1000 * path_converter accepts (Unicode) strings and their
1001 * subclasses, and bytes and their subclasses. What
1002 * it does with the argument depends on the platform:
1003 *
1004 * * On Windows, if we get a (Unicode) string we
1005 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -07001006 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007 *
1008 * * On all other platforms, strings are encoded
1009 * to bytes using PyUnicode_FSConverter, then we
1010 * extract the char * from the bytes object and
1011 * return that.
1012 *
1013 * path_converter also optionally accepts signed
1014 * integers (representing open file descriptors) instead
1015 * of path strings.
1016 *
1017 * Input fields:
1018 * path.nullable
1019 * If nonzero, the path is permitted to be None.
1020 * path.allow_fd
1021 * If nonzero, the path is permitted to be a file handle
1022 * (a signed int) instead of a string.
1023 * path.function_name
1024 * If non-NULL, path_converter will use that as the name
1025 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -07001026 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001027 * path.argument_name
1028 * If non-NULL, path_converter will use that as the name
1029 * of the parameter in error messages.
1030 * (If path.argument_name is NULL it uses "path".)
1031 *
1032 * Output fields:
1033 * path.wide
1034 * Points to the path if it was expressed as Unicode
1035 * and was not encoded. (Only used on Windows.)
1036 * path.narrow
1037 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -07001038 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +00001039 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -07001040 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001041 * path.fd
1042 * Contains a file descriptor if path.accept_fd was true
1043 * and the caller provided a signed integer instead of any
1044 * sort of string.
1045 *
1046 * WARNING: if your "path" parameter is optional, and is
1047 * unspecified, path_converter will never get called.
1048 * So if you set allow_fd, you *MUST* initialize path.fd = -1
1049 * yourself!
1050 * path.length
1051 * The length of the path in characters, if specified as
1052 * a string.
1053 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +08001054 * The original object passed in (if get a PathLike object,
1055 * the result of PyOS_FSPath() is treated as the original object).
1056 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -07001057 * path.cleanup
1058 * For internal use only. May point to a temporary object.
1059 * (Pay no attention to the man behind the curtain.)
1060 *
1061 * At most one of path.wide or path.narrow will be non-NULL.
1062 * If path was None and path.nullable was set,
1063 * or if path was an integer and path.allow_fd was set,
1064 * both path.wide and path.narrow will be NULL
1065 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +02001066 *
Larry Hastings9cf065c2012-06-22 16:30:09 -07001067 * path_converter takes care to not write to the path_t
1068 * unless it's successful. However it must reset the
1069 * "cleanup" field each time it's called.
1070 *
1071 * Use as follows:
1072 * path_t path;
1073 * memset(&path, 0, sizeof(path));
1074 * PyArg_ParseTuple(args, "O&", path_converter, &path);
1075 * // ... use values from path ...
1076 * path_cleanup(&path);
1077 *
1078 * (Note that if PyArg_Parse fails you don't need to call
1079 * path_cleanup(). However it is safe to do so.)
1080 */
1081typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +01001082 const char *function_name;
1083 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 int nullable;
1085 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001086 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -07001087#ifdef MS_WINDOWS
1088 BOOL narrow;
1089#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001090 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001091#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001092 int fd;
1093 Py_ssize_t length;
1094 PyObject *object;
1095 PyObject *cleanup;
1096} path_t;
1097
Steve Dowercc16be82016-09-08 10:35:16 -07001098#ifdef MS_WINDOWS
1099#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1100 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
1101#else
Larry Hastings2f936352014-08-05 14:04:04 +10001102#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1103 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -07001104#endif
Larry Hastings31826802013-10-19 00:09:25 -07001105
Larry Hastings9cf065c2012-06-22 16:30:09 -07001106static void
Xiang Zhang04316c42017-01-08 23:26:57 +08001107path_cleanup(path_t *path)
1108{
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001109#if !USE_UNICODE_WCHAR_CACHE
1110 wchar_t *wide = (wchar_t *)path->wide;
1111 path->wide = NULL;
1112 PyMem_Free(wide);
1113#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001114 Py_CLEAR(path->object);
1115 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001116}
1117
1118static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001119path_converter(PyObject *o, void *p)
1120{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001121 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +08001122 PyObject *bytes = NULL;
1123 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001124 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001125 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001126#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +08001127 PyObject *wo = NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001128 wchar_t *wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001129#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001130
1131#define FORMAT_EXCEPTION(exc, fmt) \
1132 PyErr_Format(exc, "%s%s" fmt, \
1133 path->function_name ? path->function_name : "", \
1134 path->function_name ? ": " : "", \
1135 path->argument_name ? path->argument_name : "path")
1136
1137 /* Py_CLEANUP_SUPPORTED support */
1138 if (o == NULL) {
1139 path_cleanup(path);
1140 return 1;
1141 }
1142
Brett Cannon3f9183b2016-08-26 14:44:48 -07001143 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +08001144 path->object = path->cleanup = NULL;
1145 /* path->object owns a reference to the original object */
1146 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001147
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001148 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001149 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001150#ifdef MS_WINDOWS
1151 path->narrow = FALSE;
1152#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001153 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001154#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001155 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001156 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001157 }
1158
Brett Cannon3f9183b2016-08-26 14:44:48 -07001159 /* Only call this here so that we don't treat the return value of
1160 os.fspath() as an fd or buffer. */
1161 is_index = path->allow_fd && PyIndex_Check(o);
1162 is_buffer = PyObject_CheckBuffer(o);
1163 is_bytes = PyBytes_Check(o);
1164 is_unicode = PyUnicode_Check(o);
1165
1166 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
1167 /* Inline PyOS_FSPath() for better error messages. */
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001168 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001169
1170 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1171 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001172 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001173 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001174 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001175 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001176 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001177 goto error_exit;
1178 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001179 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001180 is_unicode = 1;
1181 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001182 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001183 is_bytes = 1;
1184 }
1185 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001186 PyErr_Format(PyExc_TypeError,
1187 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -08001188 "not %.200s", _PyType_Name(Py_TYPE(o)),
1189 _PyType_Name(Py_TYPE(res)));
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001190 Py_DECREF(res);
1191 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001192 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001193
1194 /* still owns a reference to the original object */
1195 Py_DECREF(o);
1196 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001197 }
1198
1199 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001200#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001201#if USE_UNICODE_WCHAR_CACHE
1202_Py_COMP_DIAG_PUSH
1203_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001204 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001205_Py_COMP_DIAG_POP
1206#else /* USE_UNICODE_WCHAR_CACHE */
1207 wide = PyUnicode_AsWideCharString(o, &length);
1208#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner59799a82013-11-13 14:17:30 +01001209 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001210 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001211 }
Victor Stinner59799a82013-11-13 14:17:30 +01001212 if (length > 32767) {
1213 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001214 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001215 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001216 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001217 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001218 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001219 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001220
1221 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001222 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001223 path->fd = -1;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001224#if !USE_UNICODE_WCHAR_CACHE
1225 wide = NULL;
1226#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001227 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001228#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001229 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001230 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001231 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001232#endif
1233 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001234 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001235 bytes = o;
1236 Py_INCREF(bytes);
1237 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001238 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001239 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001240 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001241 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1242 "%s%s%s should be %s, not %.200s",
1243 path->function_name ? path->function_name : "",
1244 path->function_name ? ": " : "",
1245 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001246 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1247 "integer or None" :
1248 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1249 path->nullable ? "string, bytes, os.PathLike or None" :
1250 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001251 _PyType_Name(Py_TYPE(o)))) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001252 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001253 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001254 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001255 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001256 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001257 }
1258 }
Steve Dowercc16be82016-09-08 10:35:16 -07001259 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001260 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001261 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001262 }
1263 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001264#ifdef MS_WINDOWS
1265 path->narrow = FALSE;
1266#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001267 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001268#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001269 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001270 }
1271 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001272 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001273 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1274 path->function_name ? path->function_name : "",
1275 path->function_name ? ": " : "",
1276 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001277 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1278 "integer or None" :
1279 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1280 path->nullable ? "string, bytes, os.PathLike or None" :
1281 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001282 _PyType_Name(Py_TYPE(o)));
Xiang Zhang04316c42017-01-08 23:26:57 +08001283 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001284 }
1285
Larry Hastings9cf065c2012-06-22 16:30:09 -07001286 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001287 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001288 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001289 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001290 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001291 }
1292
Steve Dowercc16be82016-09-08 10:35:16 -07001293#ifdef MS_WINDOWS
1294 wo = PyUnicode_DecodeFSDefaultAndSize(
1295 narrow,
1296 length
1297 );
1298 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001299 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001300 }
1301
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001302#if USE_UNICODE_WCHAR_CACHE
1303_Py_COMP_DIAG_PUSH
1304_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Xiang Zhang04316c42017-01-08 23:26:57 +08001305 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001306_Py_COMP_DIAG_POP
1307#else /* USE_UNICODE_WCHAR_CACHE */
1308 wide = PyUnicode_AsWideCharString(wo, &length);
1309 Py_DECREF(wo);
1310#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001311 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001312 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001313 }
1314 if (length > 32767) {
1315 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001316 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001317 }
1318 if (wcslen(wide) != length) {
1319 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001320 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001321 }
1322 path->wide = wide;
1323 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001324 Py_DECREF(bytes);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001325#if USE_UNICODE_WCHAR_CACHE
1326 path->cleanup = wo;
1327#else /* USE_UNICODE_WCHAR_CACHE */
1328 wide = NULL;
1329#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001330#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001331 path->wide = NULL;
1332 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001333 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001334 /* Still a reference owned by path->object, don't have to
1335 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001336 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001337 }
1338 else {
1339 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001340 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001341#endif
1342 path->fd = -1;
1343
1344 success_exit:
1345 path->length = length;
1346 path->object = o;
1347 return Py_CLEANUP_SUPPORTED;
1348
1349 error_exit:
1350 Py_XDECREF(o);
1351 Py_XDECREF(bytes);
1352#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001353#if USE_UNICODE_WCHAR_CACHE
Xiang Zhang04316c42017-01-08 23:26:57 +08001354 Py_XDECREF(wo);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001355#else /* USE_UNICODE_WCHAR_CACHE */
1356 PyMem_Free(wide);
1357#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001358#endif
1359 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001360}
1361
1362static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001363argument_unavailable_error(const char *function_name, const char *argument_name)
1364{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001365 PyErr_Format(PyExc_NotImplementedError,
1366 "%s%s%s unavailable on this platform",
1367 (function_name != NULL) ? function_name : "",
1368 (function_name != NULL) ? ": ": "",
1369 argument_name);
1370}
1371
1372static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001373dir_fd_unavailable(PyObject *o, void *p)
1374{
1375 int dir_fd;
1376 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001377 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001378 if (dir_fd != DEFAULT_DIR_FD) {
1379 argument_unavailable_error(NULL, "dir_fd");
1380 return 0;
1381 }
1382 *(int *)p = dir_fd;
1383 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001384}
1385
1386static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001387fd_specified(const char *function_name, int fd)
1388{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001389 if (fd == -1)
1390 return 0;
1391
1392 argument_unavailable_error(function_name, "fd");
1393 return 1;
1394}
1395
1396static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001397follow_symlinks_specified(const char *function_name, int follow_symlinks)
1398{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001399 if (follow_symlinks)
1400 return 0;
1401
1402 argument_unavailable_error(function_name, "follow_symlinks");
1403 return 1;
1404}
1405
1406static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001407path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1408{
Steve Dowercc16be82016-09-08 10:35:16 -07001409 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1410#ifndef MS_WINDOWS
1411 && !path->narrow
1412#endif
1413 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001414 PyErr_Format(PyExc_ValueError,
1415 "%s: can't specify dir_fd without matching path",
1416 function_name);
1417 return 1;
1418 }
1419 return 0;
1420}
1421
1422static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001423dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1424{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001425 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1426 PyErr_Format(PyExc_ValueError,
1427 "%s: can't specify both dir_fd and fd",
1428 function_name);
1429 return 1;
1430 }
1431 return 0;
1432}
1433
1434static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001435fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1436 int follow_symlinks)
1437{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001438 if ((fd > 0) && (!follow_symlinks)) {
1439 PyErr_Format(PyExc_ValueError,
1440 "%s: cannot use fd and follow_symlinks together",
1441 function_name);
1442 return 1;
1443 }
1444 return 0;
1445}
1446
1447static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001448dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1449 int follow_symlinks)
1450{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001451 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1452 PyErr_Format(PyExc_ValueError,
1453 "%s: cannot use dir_fd and follow_symlinks together",
1454 function_name);
1455 return 1;
1456 }
1457 return 0;
1458}
1459
Larry Hastings2f936352014-08-05 14:04:04 +10001460#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001461 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001462#else
Larry Hastings2f936352014-08-05 14:04:04 +10001463 typedef off_t Py_off_t;
1464#endif
1465
1466static int
1467Py_off_t_converter(PyObject *arg, void *addr)
1468{
1469#ifdef HAVE_LARGEFILE_SUPPORT
1470 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1471#else
1472 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001473#endif
1474 if (PyErr_Occurred())
1475 return 0;
1476 return 1;
1477}
Larry Hastings2f936352014-08-05 14:04:04 +10001478
1479static PyObject *
1480PyLong_FromPy_off_t(Py_off_t offset)
1481{
1482#ifdef HAVE_LARGEFILE_SUPPORT
1483 return PyLong_FromLongLong(offset);
1484#else
1485 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001486#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001487}
1488
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001489#ifdef HAVE_SIGSET_T
1490/* Convert an iterable of integers to a sigset.
1491 Return 1 on success, return 0 and raise an exception on error. */
1492int
1493_Py_Sigset_Converter(PyObject *obj, void *addr)
1494{
1495 sigset_t *mask = (sigset_t *)addr;
1496 PyObject *iterator, *item;
1497 long signum;
1498 int overflow;
1499
Rémi Lapeyref0900192019-05-04 01:30:53 +02001500 // The extra parens suppress the unreachable-code warning with clang on MacOS
1501 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001502 /* Probably only if mask == NULL. */
1503 PyErr_SetFromErrno(PyExc_OSError);
1504 return 0;
1505 }
1506
1507 iterator = PyObject_GetIter(obj);
1508 if (iterator == NULL) {
1509 return 0;
1510 }
1511
1512 while ((item = PyIter_Next(iterator)) != NULL) {
1513 signum = PyLong_AsLongAndOverflow(item, &overflow);
1514 Py_DECREF(item);
1515 if (signum <= 0 || signum >= NSIG) {
1516 if (overflow || signum != -1 || !PyErr_Occurred()) {
1517 PyErr_Format(PyExc_ValueError,
1518 "signal number %ld out of range", signum);
1519 }
1520 goto error;
1521 }
1522 if (sigaddset(mask, (int)signum)) {
1523 if (errno != EINVAL) {
1524 /* Probably impossible */
1525 PyErr_SetFromErrno(PyExc_OSError);
1526 goto error;
1527 }
1528 /* For backwards compatibility, allow idioms such as
1529 * `range(1, NSIG)` but warn about invalid signal numbers
1530 */
1531 const char msg[] =
1532 "invalid signal number %ld, please use valid_signals()";
1533 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1534 goto error;
1535 }
1536 }
1537 }
1538 if (!PyErr_Occurred()) {
1539 Py_DECREF(iterator);
1540 return 1;
1541 }
1542
1543error:
1544 Py_DECREF(iterator);
1545 return 0;
1546}
1547#endif /* HAVE_SIGSET_T */
1548
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001549#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001550
1551static int
Brian Curtind25aef52011-06-13 15:16:04 -05001552win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001553{
Martin Panter70214ad2016-08-04 02:38:59 +00001554 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1555 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001556 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001557
1558 if (0 == DeviceIoControl(
1559 reparse_point_handle,
1560 FSCTL_GET_REPARSE_POINT,
1561 NULL, 0, /* in buffer */
1562 target_buffer, sizeof(target_buffer),
1563 &n_bytes_returned,
1564 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001565 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001566
1567 if (reparse_tag)
1568 *reparse_tag = rdb->ReparseTag;
1569
Brian Curtind25aef52011-06-13 15:16:04 -05001570 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001571}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001572
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001573#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001574
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001575/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001576#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001577/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001578** environ directly, we must obtain it with _NSGetEnviron(). See also
1579** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001580*/
1581#include <crt_externs.h>
pxinwrf2d7ac72019-05-21 18:46:37 +08001582#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001583extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001584#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001585
Barry Warsaw53699e91996-12-10 23:23:01 +00001586static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001587convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001588{
Victor Stinner8c62be82010-05-06 00:08:46 +00001589 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001590#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001591 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001592#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001593 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001594#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001595
Victor Stinner8c62be82010-05-06 00:08:46 +00001596 d = PyDict_New();
1597 if (d == NULL)
1598 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001599#ifdef MS_WINDOWS
1600 /* _wenviron must be initialized in this way if the program is started
1601 through main() instead of wmain(). */
1602 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001603 e = _wenviron;
Benoit Hudson723f71a2019-12-06 14:15:03 -05001604#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1605 /* environ is not accessible as an extern in a shared object on OSX; use
1606 _NSGetEnviron to resolve it. The value changes if you add environment
1607 variables between calls to Py_Initialize, so don't cache the value. */
1608 e = *_NSGetEnviron();
Victor Stinner8c62be82010-05-06 00:08:46 +00001609#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001610 e = environ;
1611#endif
1612 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001613 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001614 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001615 PyObject *k;
1616 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001617#ifdef MS_WINDOWS
1618 const wchar_t *p = wcschr(*e, L'=');
1619#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001620 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001621#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001622 if (p == NULL)
1623 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001624#ifdef MS_WINDOWS
1625 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1626#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001627 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001628#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001629 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001630 Py_DECREF(d);
1631 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001632 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001633#ifdef MS_WINDOWS
1634 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1635#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001636 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001637#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001638 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001639 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001640 Py_DECREF(d);
1641 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001642 }
Serhiy Storchakab510e102020-10-26 12:47:57 +02001643 if (PyDict_SetDefault(d, k, v) == NULL) {
1644 Py_DECREF(v);
1645 Py_DECREF(k);
1646 Py_DECREF(d);
1647 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001648 }
1649 Py_DECREF(k);
1650 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001651 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001652 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001653}
1654
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001655/* Set a POSIX-specific error from errno, and return NULL */
1656
Barry Warsawd58d7641998-07-23 16:14:40 +00001657static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001658posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001659{
Victor Stinner8c62be82010-05-06 00:08:46 +00001660 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001661}
Mark Hammondef8b6542001-05-13 08:04:26 +00001662
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001663#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001664static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001665win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001666{
Victor Stinner8c62be82010-05-06 00:08:46 +00001667 /* XXX We should pass the function name along in the future.
1668 (winreg.c also wants to pass the function name.)
1669 This would however require an additional param to the
1670 Windows error object, which is non-trivial.
1671 */
1672 errno = GetLastError();
1673 if (filename)
1674 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1675 else
1676 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001677}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001678
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001679static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001680win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001681{
1682 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001683 if (filename)
1684 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001685 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001686 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001687 filename);
1688 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001689 return PyErr_SetFromWindowsErr(err);
1690}
1691
1692static PyObject *
1693win32_error_object(const char* function, PyObject* filename)
1694{
1695 errno = GetLastError();
1696 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001697}
1698
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001699#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001700
Larry Hastings9cf065c2012-06-22 16:30:09 -07001701static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001702posix_path_object_error(PyObject *path)
1703{
1704 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1705}
1706
1707static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001708path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001709{
1710#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001711 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1712 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001713#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001714 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001715#endif
1716}
1717
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001718static PyObject *
1719path_object_error2(PyObject *path, PyObject *path2)
1720{
1721#ifdef MS_WINDOWS
1722 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1723 PyExc_OSError, 0, path, path2);
1724#else
1725 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1726#endif
1727}
1728
1729static PyObject *
1730path_error(path_t *path)
1731{
1732 return path_object_error(path->object);
1733}
Larry Hastings31826802013-10-19 00:09:25 -07001734
Larry Hastingsb0827312014-02-09 22:05:19 -08001735static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001736posix_path_error(path_t *path)
1737{
1738 return posix_path_object_error(path->object);
1739}
1740
1741static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001742path_error2(path_t *path, path_t *path2)
1743{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001744 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001745}
1746
1747
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001748/* POSIX generic methods */
1749
Larry Hastings2f936352014-08-05 14:04:04 +10001750static PyObject *
1751posix_fildes_fd(int fd, int (*func)(int))
1752{
1753 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001754 int async_err = 0;
1755
1756 do {
1757 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001758 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001759 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001760 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001761 Py_END_ALLOW_THREADS
1762 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1763 if (res != 0)
1764 return (!async_err) ? posix_error() : NULL;
1765 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001766}
Guido van Rossum21142a01999-01-08 21:05:37 +00001767
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001768
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001769#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001770/* This is a reimplementation of the C library's chdir function,
1771 but one that produces Win32 errors instead of DOS error codes.
1772 chdir is essentially a wrapper around SetCurrentDirectory; however,
1773 it also needs to set "magic" environment variables indicating
1774 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001775static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001776win32_wchdir(LPCWSTR path)
1777{
Victor Stinnered537822015-12-13 21:40:26 +01001778 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001779 int result;
1780 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001781
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 if(!SetCurrentDirectoryW(path))
1783 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001784 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 if (!result)
1786 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001787 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001788 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001789 if (!new_path) {
1790 SetLastError(ERROR_OUTOFMEMORY);
1791 return FALSE;
1792 }
1793 result = GetCurrentDirectoryW(result, new_path);
1794 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001795 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001796 return FALSE;
1797 }
1798 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001799 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1800 wcsncmp(new_path, L"//", 2) == 0);
1801 if (!is_unc_like_path) {
1802 env[1] = new_path[0];
1803 result = SetEnvironmentVariableW(env, new_path);
1804 }
Victor Stinnered537822015-12-13 21:40:26 +01001805 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001806 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001807 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001808}
1809#endif
1810
Martin v. Löwis14694662006-02-03 12:54:16 +00001811#ifdef MS_WINDOWS
1812/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1813 - time stamps are restricted to second resolution
1814 - file modification times suffer from forth-and-back conversions between
1815 UTC and local time
1816 Therefore, we implement our own stat, based on the Win32 API directly.
1817*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001818#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001819#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001820#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001821
Victor Stinner6036e442015-03-08 01:58:04 +01001822static void
Steve Dowercc16be82016-09-08 10:35:16 -07001823find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1824 BY_HANDLE_FILE_INFORMATION *info,
1825 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001826{
1827 memset(info, 0, sizeof(*info));
1828 info->dwFileAttributes = pFileData->dwFileAttributes;
1829 info->ftCreationTime = pFileData->ftCreationTime;
1830 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1831 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1832 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1833 info->nFileSizeLow = pFileData->nFileSizeLow;
1834/* info->nNumberOfLinks = 1; */
1835 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1836 *reparse_tag = pFileData->dwReserved0;
1837 else
1838 *reparse_tag = 0;
1839}
1840
Guido van Rossumd8faa362007-04-27 19:54:29 +00001841static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001842attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001843{
Victor Stinner8c62be82010-05-06 00:08:46 +00001844 HANDLE hFindFile;
1845 WIN32_FIND_DATAW FileData;
1846 hFindFile = FindFirstFileW(pszFile, &FileData);
1847 if (hFindFile == INVALID_HANDLE_VALUE)
1848 return FALSE;
1849 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001850 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001851 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001852}
1853
Brian Curtind25aef52011-06-13 15:16:04 -05001854static int
Steve Dowercc16be82016-09-08 10:35:16 -07001855win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001856 BOOL traverse)
1857{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001858 HANDLE hFile;
1859 BY_HANDLE_FILE_INFORMATION fileInfo;
1860 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1861 DWORD fileType, error;
1862 BOOL isUnhandledTag = FALSE;
1863 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001864
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001865 DWORD access = FILE_READ_ATTRIBUTES;
1866 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1867 if (!traverse) {
1868 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1869 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001870
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001871 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001872 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001873 /* Either the path doesn't exist, or the caller lacks access. */
1874 error = GetLastError();
1875 switch (error) {
1876 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1877 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1878 /* Try reading the parent directory. */
1879 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1880 /* Cannot read the parent directory. */
1881 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001882 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001883 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001884 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1885 if (traverse ||
1886 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1887 /* The stat call has to traverse but cannot, so fail. */
1888 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001889 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001890 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001891 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001892 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001893
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001894 case ERROR_INVALID_PARAMETER:
1895 /* \\.\con requires read or write access. */
1896 hFile = CreateFileW(path, access | GENERIC_READ,
1897 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1898 OPEN_EXISTING, flags, NULL);
1899 if (hFile == INVALID_HANDLE_VALUE) {
1900 SetLastError(error);
1901 return -1;
1902 }
1903 break;
1904
1905 case ERROR_CANT_ACCESS_FILE:
1906 /* bpo37834: open unhandled reparse points if traverse fails. */
1907 if (traverse) {
1908 traverse = FALSE;
1909 isUnhandledTag = TRUE;
1910 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1911 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1912 }
1913 if (hFile == INVALID_HANDLE_VALUE) {
1914 SetLastError(error);
1915 return -1;
1916 }
1917 break;
1918
1919 default:
1920 return -1;
1921 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001922 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001923
1924 if (hFile != INVALID_HANDLE_VALUE) {
1925 /* Handle types other than files on disk. */
1926 fileType = GetFileType(hFile);
1927 if (fileType != FILE_TYPE_DISK) {
1928 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1929 retval = -1;
1930 goto cleanup;
1931 }
1932 DWORD fileAttributes = GetFileAttributesW(path);
1933 memset(result, 0, sizeof(*result));
1934 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1935 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1936 /* \\.\pipe\ or \\.\mailslot\ */
1937 result->st_mode = _S_IFDIR;
1938 } else if (fileType == FILE_TYPE_CHAR) {
1939 /* \\.\nul */
1940 result->st_mode = _S_IFCHR;
1941 } else if (fileType == FILE_TYPE_PIPE) {
1942 /* \\.\pipe\spam */
1943 result->st_mode = _S_IFIFO;
1944 }
1945 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1946 goto cleanup;
1947 }
1948
1949 /* Query the reparse tag, and traverse a non-link. */
1950 if (!traverse) {
1951 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1952 &tagInfo, sizeof(tagInfo))) {
1953 /* Allow devices that do not support FileAttributeTagInfo. */
1954 switch (GetLastError()) {
1955 case ERROR_INVALID_PARAMETER:
1956 case ERROR_INVALID_FUNCTION:
1957 case ERROR_NOT_SUPPORTED:
1958 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1959 tagInfo.ReparseTag = 0;
1960 break;
1961 default:
1962 retval = -1;
1963 goto cleanup;
1964 }
1965 } else if (tagInfo.FileAttributes &
1966 FILE_ATTRIBUTE_REPARSE_POINT) {
1967 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1968 if (isUnhandledTag) {
1969 /* Traversing previously failed for either this link
1970 or its target. */
1971 SetLastError(ERROR_CANT_ACCESS_FILE);
1972 retval = -1;
1973 goto cleanup;
1974 }
1975 /* Traverse a non-link, but not if traversing already failed
1976 for an unhandled tag. */
1977 } else if (!isUnhandledTag) {
1978 CloseHandle(hFile);
1979 return win32_xstat_impl(path, result, TRUE);
1980 }
1981 }
1982 }
1983
1984 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1985 switch (GetLastError()) {
1986 case ERROR_INVALID_PARAMETER:
1987 case ERROR_INVALID_FUNCTION:
1988 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07001989 /* Volumes and physical disks are block devices, e.g.
1990 \\.\C: and \\.\PhysicalDrive0. */
1991 memset(result, 0, sizeof(*result));
1992 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001993 goto cleanup;
1994 }
Steve Dower772ec0f2019-09-04 14:42:54 -07001995 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001996 goto cleanup;
1997 }
1998 }
1999
2000 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
2001
2002 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
2003 /* Fix the file execute permissions. This hack sets S_IEXEC if
2004 the filename has an extension that is commonly used by files
2005 that CreateProcessW can execute. A real implementation calls
2006 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
2007 AccessCheck to check for generic read, write, and execute
2008 access. */
2009 const wchar_t *fileExtension = wcsrchr(path, '.');
2010 if (fileExtension) {
2011 if (_wcsicmp(fileExtension, L".exe") == 0 ||
2012 _wcsicmp(fileExtension, L".bat") == 0 ||
2013 _wcsicmp(fileExtension, L".cmd") == 0 ||
2014 _wcsicmp(fileExtension, L".com") == 0) {
2015 result->st_mode |= 0111;
2016 }
2017 }
2018 }
2019
2020cleanup:
2021 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07002022 /* Preserve last error if we are failing */
2023 error = retval ? GetLastError() : 0;
2024 if (!CloseHandle(hFile)) {
2025 retval = -1;
2026 } else if (retval) {
2027 /* Restore last error */
2028 SetLastError(error);
2029 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002030 }
2031
2032 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00002033}
2034
2035static int
Steve Dowercc16be82016-09-08 10:35:16 -07002036win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00002037{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002038 /* Protocol violation: we explicitly clear errno, instead of
2039 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05002040 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002041 errno = 0;
2042 return code;
2043}
Brian Curtind25aef52011-06-13 15:16:04 -05002044/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00002045
2046 In Posix, stat automatically traverses symlinks and returns the stat
2047 structure for the target. In Windows, the equivalent GetFileAttributes by
2048 default does not traverse symlinks and instead returns attributes for
2049 the symlink.
2050
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002051 Instead, we will open the file (which *does* traverse symlinks by default)
2052 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00002053
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002054static int
Steve Dowercc16be82016-09-08 10:35:16 -07002055win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00002056{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002057 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00002058}
2059
Victor Stinner8c62be82010-05-06 00:08:46 +00002060static int
Steve Dowercc16be82016-09-08 10:35:16 -07002061win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00002062{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002063 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00002064}
2065
Martin v. Löwis14694662006-02-03 12:54:16 +00002066#endif /* MS_WINDOWS */
2067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002068PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002069"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002070This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002071 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002072or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
2073\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002074Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
2075or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002076\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002077See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002078
2079static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002080 {"st_mode", "protection bits"},
2081 {"st_ino", "inode"},
2082 {"st_dev", "device"},
2083 {"st_nlink", "number of hard links"},
2084 {"st_uid", "user ID of owner"},
2085 {"st_gid", "group ID of owner"},
2086 {"st_size", "total size, in bytes"},
2087 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
2088 {NULL, "integer time of last access"},
2089 {NULL, "integer time of last modification"},
2090 {NULL, "integer time of last change"},
2091 {"st_atime", "time of last access"},
2092 {"st_mtime", "time of last modification"},
2093 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07002094 {"st_atime_ns", "time of last access in nanoseconds"},
2095 {"st_mtime_ns", "time of last modification in nanoseconds"},
2096 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002097#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002098 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002099#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002100#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002101 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002102#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002103#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002104 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002105#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002106#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002107 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002108#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002109#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002110 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002111#endif
2112#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002114#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002115#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2116 {"st_file_attributes", "Windows file attribute bits"},
2117#endif
jcea6c51d512018-01-28 14:00:08 +01002118#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2119 {"st_fstype", "Type of filesystem"},
2120#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002121#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2122 {"st_reparse_tag", "Windows reparse tag"},
2123#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002124 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002125};
2126
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002127#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002128#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002129#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002130#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002131#endif
2132
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002133#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002134#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2135#else
2136#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2137#endif
2138
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002139#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002140#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2141#else
2142#define ST_RDEV_IDX ST_BLOCKS_IDX
2143#endif
2144
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002145#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2146#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2147#else
2148#define ST_FLAGS_IDX ST_RDEV_IDX
2149#endif
2150
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002151#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002152#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002153#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002154#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002155#endif
2156
2157#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2158#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2159#else
2160#define ST_BIRTHTIME_IDX ST_GEN_IDX
2161#endif
2162
Zachary Ware63f277b2014-06-19 09:46:37 -05002163#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2164#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2165#else
2166#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2167#endif
2168
jcea6c51d512018-01-28 14:00:08 +01002169#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2170#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2171#else
2172#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2173#endif
2174
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002175#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2176#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2177#else
2178#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2179#endif
2180
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002181static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002182 "stat_result", /* name */
2183 stat_result__doc__, /* doc */
2184 stat_result_fields,
2185 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002186};
2187
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002188PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002189"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2190This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002191 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002192or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002193\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002194See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002195
2196static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002197 {"f_bsize", },
2198 {"f_frsize", },
2199 {"f_blocks", },
2200 {"f_bfree", },
2201 {"f_bavail", },
2202 {"f_files", },
2203 {"f_ffree", },
2204 {"f_favail", },
2205 {"f_flag", },
2206 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002207 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002208 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002209};
2210
2211static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002212 "statvfs_result", /* name */
2213 statvfs_result__doc__, /* doc */
2214 statvfs_result_fields,
2215 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002216};
2217
Ross Lagerwall7807c352011-03-17 20:20:30 +02002218#if defined(HAVE_WAITID) && !defined(__APPLE__)
2219PyDoc_STRVAR(waitid_result__doc__,
2220"waitid_result: Result from waitid.\n\n\
2221This object may be accessed either as a tuple of\n\
2222 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2223or via the attributes si_pid, si_uid, and so on.\n\
2224\n\
2225See os.waitid for more information.");
2226
2227static PyStructSequence_Field waitid_result_fields[] = {
2228 {"si_pid", },
2229 {"si_uid", },
2230 {"si_signo", },
2231 {"si_status", },
2232 {"si_code", },
2233 {0}
2234};
2235
2236static PyStructSequence_Desc waitid_result_desc = {
2237 "waitid_result", /* name */
2238 waitid_result__doc__, /* doc */
2239 waitid_result_fields,
2240 5
2241};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002242#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002243static newfunc structseq_new;
2244
2245static PyObject *
2246statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2247{
Victor Stinner8c62be82010-05-06 00:08:46 +00002248 PyStructSequence *result;
2249 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002250
Victor Stinner8c62be82010-05-06 00:08:46 +00002251 result = (PyStructSequence*)structseq_new(type, args, kwds);
2252 if (!result)
2253 return NULL;
2254 /* If we have been initialized from a tuple,
2255 st_?time might be set to None. Initialize it
2256 from the int slots. */
2257 for (i = 7; i <= 9; i++) {
2258 if (result->ob_item[i+3] == Py_None) {
2259 Py_DECREF(Py_None);
2260 Py_INCREF(result->ob_item[i]);
2261 result->ob_item[i+3] = result->ob_item[i];
2262 }
2263 }
2264 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002265}
2266
Eddie Elizondob3966632019-11-05 07:16:14 -08002267static int
2268_posix_clear(PyObject *module)
2269{
Victor Stinner97f33c32020-05-14 18:05:58 +02002270 _posixstate *state = get_posix_state(module);
2271 Py_CLEAR(state->billion);
2272 Py_CLEAR(state->DirEntryType);
2273 Py_CLEAR(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002274#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002275 Py_CLEAR(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002276#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002277 Py_CLEAR(state->StatResultType);
2278 Py_CLEAR(state->StatVFSResultType);
2279 Py_CLEAR(state->TerminalSizeType);
2280 Py_CLEAR(state->TimesResultType);
2281 Py_CLEAR(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002282#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002283 Py_CLEAR(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002284#endif
2285#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002286 Py_CLEAR(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002287#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002288 Py_CLEAR(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002289 return 0;
2290}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002291
Eddie Elizondob3966632019-11-05 07:16:14 -08002292static int
2293_posix_traverse(PyObject *module, visitproc visit, void *arg)
2294{
Victor Stinner97f33c32020-05-14 18:05:58 +02002295 _posixstate *state = get_posix_state(module);
2296 Py_VISIT(state->billion);
2297 Py_VISIT(state->DirEntryType);
2298 Py_VISIT(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002299#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002300 Py_VISIT(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002301#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002302 Py_VISIT(state->StatResultType);
2303 Py_VISIT(state->StatVFSResultType);
2304 Py_VISIT(state->TerminalSizeType);
2305 Py_VISIT(state->TimesResultType);
2306 Py_VISIT(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002307#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002308 Py_VISIT(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002309#endif
2310#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002311 Py_VISIT(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002312#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002313 Py_VISIT(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002314 return 0;
2315}
2316
2317static void
2318_posix_free(void *module)
2319{
2320 _posix_clear((PyObject *)module);
2321}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002322
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002323static void
Victor Stinner1c2fa782020-05-10 11:05:29 +02002324fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002325{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002326 PyObject *s = _PyLong_FromTime_t(sec);
2327 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2328 PyObject *s_in_ns = NULL;
2329 PyObject *ns_total = NULL;
2330 PyObject *float_s = NULL;
2331
2332 if (!(s && ns_fractional))
2333 goto exit;
2334
Victor Stinner1c2fa782020-05-10 11:05:29 +02002335 s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002336 if (!s_in_ns)
2337 goto exit;
2338
2339 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2340 if (!ns_total)
2341 goto exit;
2342
Victor Stinner01b5aab2017-10-24 02:02:00 -07002343 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2344 if (!float_s) {
2345 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002346 }
2347
2348 PyStructSequence_SET_ITEM(v, index, s);
2349 PyStructSequence_SET_ITEM(v, index+3, float_s);
2350 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2351 s = NULL;
2352 float_s = NULL;
2353 ns_total = NULL;
2354exit:
2355 Py_XDECREF(s);
2356 Py_XDECREF(ns_fractional);
2357 Py_XDECREF(s_in_ns);
2358 Py_XDECREF(ns_total);
2359 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002360}
2361
Tim Peters5aa91602002-01-30 05:46:57 +00002362/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002363 (used by posix_stat() and posix_fstat()) */
2364static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +02002365_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002366{
Victor Stinner8c62be82010-05-06 00:08:46 +00002367 unsigned long ansec, mnsec, cnsec;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002368 PyObject *StatResultType = get_posix_state(module)->StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08002369 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002370 if (v == NULL)
2371 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002372
Victor Stinner8c62be82010-05-06 00:08:46 +00002373 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002374 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002375 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002376#ifdef MS_WINDOWS
2377 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002378#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002379 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002380#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002381 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002382#if defined(MS_WINDOWS)
2383 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2384 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2385#else
2386 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2387 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2388#endif
xdegaye50e86032017-05-22 11:15:08 +02002389 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2390 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002391
Martin v. Löwis14694662006-02-03 12:54:16 +00002392#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002393 ansec = st->st_atim.tv_nsec;
2394 mnsec = st->st_mtim.tv_nsec;
2395 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002396#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002397 ansec = st->st_atimespec.tv_nsec;
2398 mnsec = st->st_mtimespec.tv_nsec;
2399 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002400#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002401 ansec = st->st_atime_nsec;
2402 mnsec = st->st_mtime_nsec;
2403 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002404#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002405 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002406#endif
Victor Stinner1c2fa782020-05-10 11:05:29 +02002407 fill_time(module, v, 7, st->st_atime, ansec);
2408 fill_time(module, v, 8, st->st_mtime, mnsec);
2409 fill_time(module, v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002410
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002411#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002412 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2413 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002414#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002415#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002416 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2417 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002418#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002419#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002420 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2421 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002422#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002423#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002424 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2425 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002426#endif
2427#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002428 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002429 PyObject *val;
2430 unsigned long bsec,bnsec;
2431 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002432#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002433 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002434#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002435 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002436#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002437 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002438 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2439 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002440 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002441#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002442#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002443 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2444 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002445#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002446#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2447 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2448 PyLong_FromUnsignedLong(st->st_file_attributes));
2449#endif
jcea6c51d512018-01-28 14:00:08 +01002450#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2451 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2452 PyUnicode_FromString(st->st_fstype));
2453#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002454#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2455 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2456 PyLong_FromUnsignedLong(st->st_reparse_tag));
2457#endif
Fred Drake699f3522000-06-29 21:12:41 +00002458
Victor Stinner8c62be82010-05-06 00:08:46 +00002459 if (PyErr_Occurred()) {
2460 Py_DECREF(v);
2461 return NULL;
2462 }
Fred Drake699f3522000-06-29 21:12:41 +00002463
Victor Stinner8c62be82010-05-06 00:08:46 +00002464 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002465}
2466
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002467/* POSIX methods */
2468
Guido van Rossum94f6f721999-01-06 18:42:14 +00002469
2470static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02002471posix_do_stat(PyObject *module, const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002472 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002473{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002474 STRUCT_STAT st;
2475 int result;
2476
Ronald Oussoren41761932020-11-08 10:05:27 +01002477#ifdef HAVE_FSTATAT
2478 int fstatat_unavailable = 0;
2479#endif
2480
Larry Hastings9cf065c2012-06-22 16:30:09 -07002481#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2482 if (follow_symlinks_specified(function_name, follow_symlinks))
2483 return NULL;
2484#endif
2485
2486 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2487 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2488 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2489 return NULL;
2490
2491 Py_BEGIN_ALLOW_THREADS
2492 if (path->fd != -1)
2493 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002494#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002495 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002496 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002497 else
Steve Dowercc16be82016-09-08 10:35:16 -07002498 result = win32_lstat(path->wide, &st);
2499#else
2500 else
2501#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002502 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2503 result = LSTAT(path->narrow, &st);
2504 else
Steve Dowercc16be82016-09-08 10:35:16 -07002505#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002506#ifdef HAVE_FSTATAT
Ronald Oussoren41761932020-11-08 10:05:27 +01002507 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2508 if (HAVE_FSTATAT_RUNTIME) {
2509 result = fstatat(dir_fd, path->narrow, &st,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002510 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +01002511
2512 } else {
2513 fstatat_unavailable = 1;
2514 }
2515 } else
Steve Dowercc16be82016-09-08 10:35:16 -07002516#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002517 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002518#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002519 Py_END_ALLOW_THREADS
2520
Ronald Oussoren41761932020-11-08 10:05:27 +01002521#ifdef HAVE_FSTATAT
2522 if (fstatat_unavailable) {
2523 argument_unavailable_error("stat", "dir_fd");
2524 return NULL;
2525 }
2526#endif
2527
Victor Stinner292c8352012-10-30 02:17:38 +01002528 if (result != 0) {
2529 return path_error(path);
2530 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002531
Victor Stinner1c2fa782020-05-10 11:05:29 +02002532 return _pystat_fromstructstat(module, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002533}
2534
Larry Hastings2f936352014-08-05 14:04:04 +10002535/*[python input]
2536
2537for s in """
2538
2539FACCESSAT
2540FCHMODAT
2541FCHOWNAT
2542FSTATAT
2543LINKAT
2544MKDIRAT
2545MKFIFOAT
2546MKNODAT
2547OPENAT
2548READLINKAT
2549SYMLINKAT
2550UNLINKAT
2551
2552""".strip().split():
2553 s = s.strip()
2554 print("""
2555#ifdef HAVE_{s}
2556 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002557#else
Larry Hastings2f936352014-08-05 14:04:04 +10002558 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002559#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002560""".rstrip().format(s=s))
2561
2562for s in """
2563
2564FCHDIR
2565FCHMOD
2566FCHOWN
2567FDOPENDIR
2568FEXECVE
2569FPATHCONF
2570FSTATVFS
2571FTRUNCATE
2572
2573""".strip().split():
2574 s = s.strip()
2575 print("""
2576#ifdef HAVE_{s}
2577 #define PATH_HAVE_{s} 1
2578#else
2579 #define PATH_HAVE_{s} 0
2580#endif
2581
2582""".rstrip().format(s=s))
2583[python start generated code]*/
2584
2585#ifdef HAVE_FACCESSAT
2586 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2587#else
2588 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2589#endif
2590
2591#ifdef HAVE_FCHMODAT
2592 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2593#else
2594 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2595#endif
2596
2597#ifdef HAVE_FCHOWNAT
2598 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2599#else
2600 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2601#endif
2602
2603#ifdef HAVE_FSTATAT
2604 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2605#else
2606 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2607#endif
2608
2609#ifdef HAVE_LINKAT
2610 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2611#else
2612 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2613#endif
2614
2615#ifdef HAVE_MKDIRAT
2616 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2617#else
2618 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2619#endif
2620
2621#ifdef HAVE_MKFIFOAT
2622 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2623#else
2624 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2625#endif
2626
2627#ifdef HAVE_MKNODAT
2628 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2629#else
2630 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2631#endif
2632
2633#ifdef HAVE_OPENAT
2634 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2635#else
2636 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2637#endif
2638
2639#ifdef HAVE_READLINKAT
2640 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2641#else
2642 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2643#endif
2644
2645#ifdef HAVE_SYMLINKAT
2646 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2647#else
2648 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2649#endif
2650
2651#ifdef HAVE_UNLINKAT
2652 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2653#else
2654 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2655#endif
2656
2657#ifdef HAVE_FCHDIR
2658 #define PATH_HAVE_FCHDIR 1
2659#else
2660 #define PATH_HAVE_FCHDIR 0
2661#endif
2662
2663#ifdef HAVE_FCHMOD
2664 #define PATH_HAVE_FCHMOD 1
2665#else
2666 #define PATH_HAVE_FCHMOD 0
2667#endif
2668
2669#ifdef HAVE_FCHOWN
2670 #define PATH_HAVE_FCHOWN 1
2671#else
2672 #define PATH_HAVE_FCHOWN 0
2673#endif
2674
2675#ifdef HAVE_FDOPENDIR
2676 #define PATH_HAVE_FDOPENDIR 1
2677#else
2678 #define PATH_HAVE_FDOPENDIR 0
2679#endif
2680
2681#ifdef HAVE_FEXECVE
2682 #define PATH_HAVE_FEXECVE 1
2683#else
2684 #define PATH_HAVE_FEXECVE 0
2685#endif
2686
2687#ifdef HAVE_FPATHCONF
2688 #define PATH_HAVE_FPATHCONF 1
2689#else
2690 #define PATH_HAVE_FPATHCONF 0
2691#endif
2692
2693#ifdef HAVE_FSTATVFS
2694 #define PATH_HAVE_FSTATVFS 1
2695#else
2696 #define PATH_HAVE_FSTATVFS 0
2697#endif
2698
2699#ifdef HAVE_FTRUNCATE
2700 #define PATH_HAVE_FTRUNCATE 1
2701#else
2702 #define PATH_HAVE_FTRUNCATE 0
2703#endif
2704/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002705
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002706#ifdef MS_WINDOWS
2707 #undef PATH_HAVE_FTRUNCATE
2708 #define PATH_HAVE_FTRUNCATE 1
2709#endif
Larry Hastings31826802013-10-19 00:09:25 -07002710
Larry Hastings61272b72014-01-07 12:41:53 -08002711/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002712
2713class path_t_converter(CConverter):
2714
2715 type = "path_t"
2716 impl_by_reference = True
2717 parse_by_reference = True
2718
2719 converter = 'path_converter'
2720
2721 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002722 # right now path_t doesn't support default values.
2723 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002724 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002725 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002726
Larry Hastings2f936352014-08-05 14:04:04 +10002727 if self.c_default not in (None, 'Py_None'):
2728 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002729
2730 self.nullable = nullable
2731 self.allow_fd = allow_fd
2732
Larry Hastings7726ac92014-01-31 22:03:12 -08002733 def pre_render(self):
2734 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002735 if isinstance(value, str):
2736 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002737 return str(int(bool(value)))
2738
2739 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002740 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002741 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002742 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002743 strify(self.nullable),
2744 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002745 )
2746
2747 def cleanup(self):
2748 return "path_cleanup(&" + self.name + ");\n"
2749
2750
2751class dir_fd_converter(CConverter):
2752 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002753
Larry Hastings2f936352014-08-05 14:04:04 +10002754 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002755 if self.default in (unspecified, None):
2756 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002757 if isinstance(requires, str):
2758 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2759 else:
2760 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002761
Larry Hastings2f936352014-08-05 14:04:04 +10002762class uid_t_converter(CConverter):
2763 type = "uid_t"
2764 converter = '_Py_Uid_Converter'
2765
2766class gid_t_converter(CConverter):
2767 type = "gid_t"
2768 converter = '_Py_Gid_Converter'
2769
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002770class dev_t_converter(CConverter):
2771 type = 'dev_t'
2772 converter = '_Py_Dev_Converter'
2773
2774class dev_t_return_converter(unsigned_long_return_converter):
2775 type = 'dev_t'
2776 conversion_fn = '_PyLong_FromDev'
2777 unsigned_cast = '(dev_t)'
2778
Larry Hastings2f936352014-08-05 14:04:04 +10002779class FSConverter_converter(CConverter):
2780 type = 'PyObject *'
2781 converter = 'PyUnicode_FSConverter'
2782 def converter_init(self):
2783 if self.default is not unspecified:
2784 fail("FSConverter_converter does not support default values")
2785 self.c_default = 'NULL'
2786
2787 def cleanup(self):
2788 return "Py_XDECREF(" + self.name + ");\n"
2789
2790class pid_t_converter(CConverter):
2791 type = 'pid_t'
2792 format_unit = '" _Py_PARSE_PID "'
2793
2794class idtype_t_converter(int_converter):
2795 type = 'idtype_t'
2796
2797class id_t_converter(CConverter):
2798 type = 'id_t'
2799 format_unit = '" _Py_PARSE_PID "'
2800
Benjamin Petersonca470632016-09-06 13:47:26 -07002801class intptr_t_converter(CConverter):
2802 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002803 format_unit = '" _Py_PARSE_INTPTR "'
2804
2805class Py_off_t_converter(CConverter):
2806 type = 'Py_off_t'
2807 converter = 'Py_off_t_converter'
2808
2809class Py_off_t_return_converter(long_return_converter):
2810 type = 'Py_off_t'
2811 conversion_fn = 'PyLong_FromPy_off_t'
2812
2813class path_confname_converter(CConverter):
2814 type="int"
2815 converter="conv_path_confname"
2816
2817class confstr_confname_converter(path_confname_converter):
2818 converter='conv_confstr_confname'
2819
2820class sysconf_confname_converter(path_confname_converter):
2821 converter="conv_sysconf_confname"
2822
Larry Hastings61272b72014-01-07 12:41:53 -08002823[python start generated code]*/
Serhiy Storchaka9975cc52020-10-09 23:00:45 +03002824/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/
Larry Hastings31826802013-10-19 00:09:25 -07002825
Larry Hastings61272b72014-01-07 12:41:53 -08002826/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002827
Larry Hastings2a727912014-01-16 11:32:01 -08002828os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002829
2830 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002831 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002832 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002833
2834 *
2835
Larry Hastings2f936352014-08-05 14:04:04 +10002836 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002837 If not None, it should be a file descriptor open to a directory,
2838 and path should be a relative string; path will then be relative to
2839 that directory.
2840
2841 follow_symlinks: bool = True
2842 If False, and the last element of the path is a symbolic link,
2843 stat will examine the symbolic link itself instead of the file
2844 the link points to.
2845
2846Perform a stat system call on the given path.
2847
2848dir_fd and follow_symlinks may not be implemented
2849 on your platform. If they are unavailable, using them will raise a
2850 NotImplementedError.
2851
2852It's an error to use dir_fd or follow_symlinks when specifying path as
2853 an open file descriptor.
2854
Larry Hastings61272b72014-01-07 12:41:53 -08002855[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002856
Larry Hastings31826802013-10-19 00:09:25 -07002857static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002858os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002859/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002860{
Victor Stinner1c2fa782020-05-10 11:05:29 +02002861 return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002862}
2863
Larry Hastings2f936352014-08-05 14:04:04 +10002864
2865/*[clinic input]
2866os.lstat
2867
2868 path : path_t
2869
2870 *
2871
2872 dir_fd : dir_fd(requires='fstatat') = None
2873
2874Perform a stat system call on the given path, without following symbolic links.
2875
2876Like stat(), but do not follow symbolic links.
2877Equivalent to stat(path, follow_symlinks=False).
2878[clinic start generated code]*/
2879
Larry Hastings2f936352014-08-05 14:04:04 +10002880static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002881os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2882/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002883{
2884 int follow_symlinks = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002885 return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10002886}
Larry Hastings31826802013-10-19 00:09:25 -07002887
Larry Hastings2f936352014-08-05 14:04:04 +10002888
Larry Hastings61272b72014-01-07 12:41:53 -08002889/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002890os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002891
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002892 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002893 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002894
2895 mode: int
2896 Operating-system mode bitfield. Can be F_OK to test existence,
2897 or the inclusive-OR of R_OK, W_OK, and X_OK.
2898
2899 *
2900
Larry Hastings2f936352014-08-05 14:04:04 +10002901 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002902 If not None, it should be a file descriptor open to a directory,
2903 and path should be relative; path will then be relative to that
2904 directory.
2905
2906 effective_ids: bool = False
2907 If True, access will use the effective uid/gid instead of
2908 the real uid/gid.
2909
2910 follow_symlinks: bool = True
2911 If False, and the last element of the path is a symbolic link,
2912 access will examine the symbolic link itself instead of the file
2913 the link points to.
2914
2915Use the real uid/gid to test for access to a path.
2916
2917{parameters}
2918dir_fd, effective_ids, and follow_symlinks may not be implemented
2919 on your platform. If they are unavailable, using them will raise a
2920 NotImplementedError.
2921
2922Note that most operations will use the effective uid/gid, therefore this
2923 routine can be used in a suid/sgid environment to test if the invoking user
2924 has the specified access to the path.
2925
Larry Hastings61272b72014-01-07 12:41:53 -08002926[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002927
Larry Hastings2f936352014-08-05 14:04:04 +10002928static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002929os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002930 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002931/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002932{
Larry Hastings2f936352014-08-05 14:04:04 +10002933 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002934
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002935#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002937#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002938 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002939#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002940
Ronald Oussoren41761932020-11-08 10:05:27 +01002941#ifdef HAVE_FACCESSAT
2942 int faccessat_unavailable = 0;
2943#endif
2944
Larry Hastings9cf065c2012-06-22 16:30:09 -07002945#ifndef HAVE_FACCESSAT
2946 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002947 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002948
2949 if (effective_ids) {
2950 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002951 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002952 }
2953#endif
2954
2955#ifdef MS_WINDOWS
2956 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002957 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002958 Py_END_ALLOW_THREADS
2959
2960 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002961 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962 * * we didn't get a -1, and
2963 * * write access wasn't requested,
2964 * * or the file isn't read-only,
2965 * * or it's a directory.
2966 * (Directories cannot be read-only on Windows.)
2967 */
Larry Hastings2f936352014-08-05 14:04:04 +10002968 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002969 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002970 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002971 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972#else
2973
2974 Py_BEGIN_ALLOW_THREADS
2975#ifdef HAVE_FACCESSAT
2976 if ((dir_fd != DEFAULT_DIR_FD) ||
2977 effective_ids ||
2978 !follow_symlinks) {
Ronald Oussoren41761932020-11-08 10:05:27 +01002979
2980 if (HAVE_FACCESSAT_RUNTIME) {
2981 int flags = 0;
2982 if (!follow_symlinks)
2983 flags |= AT_SYMLINK_NOFOLLOW;
2984 if (effective_ids)
2985 flags |= AT_EACCESS;
2986 result = faccessat(dir_fd, path->narrow, mode, flags);
2987 } else {
2988 faccessat_unavailable = 1;
2989 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002990 }
2991 else
2992#endif
Larry Hastings31826802013-10-19 00:09:25 -07002993 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01002995
2996#ifdef HAVE_FACCESSAT
2997 if (faccessat_unavailable) {
2998 if (dir_fd != DEFAULT_DIR_FD) {
2999 argument_unavailable_error("access", "dir_fd");
3000 return -1;
3001 }
3002 if (follow_symlinks_specified("access", follow_symlinks))
3003 return -1;
3004
3005 if (effective_ids) {
3006 argument_unavailable_error("access", "effective_ids");
3007 return -1;
3008 }
3009 /* should be unreachable */
3010 return -1;
3011 }
3012#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003013 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003014#endif
3015
Larry Hastings9cf065c2012-06-22 16:30:09 -07003016 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003017}
3018
Guido van Rossumd371ff11999-01-25 16:12:23 +00003019#ifndef F_OK
3020#define F_OK 0
3021#endif
3022#ifndef R_OK
3023#define R_OK 4
3024#endif
3025#ifndef W_OK
3026#define W_OK 2
3027#endif
3028#ifndef X_OK
3029#define X_OK 1
3030#endif
3031
Larry Hastings31826802013-10-19 00:09:25 -07003032
Guido van Rossumd371ff11999-01-25 16:12:23 +00003033#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08003034/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003035os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07003036
3037 fd: int
3038 Integer file descriptor handle.
3039
3040 /
3041
3042Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08003043[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07003044
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003045static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003046os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003047/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07003048{
Guido van Rossum94f6f721999-01-06 18:42:14 +00003049
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02003050 long size = sysconf(_SC_TTY_NAME_MAX);
3051 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003052 return posix_error();
3053 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02003054 char *buffer = (char *)PyMem_RawMalloc(size);
3055 if (buffer == NULL) {
3056 return PyErr_NoMemory();
3057 }
3058 int ret = ttyname_r(fd, buffer, size);
3059 if (ret != 0) {
3060 PyMem_RawFree(buffer);
3061 errno = ret;
3062 return posix_error();
3063 }
3064 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
3065 PyMem_RawFree(buffer);
3066 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003067}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003068#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003069
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003070#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10003071/*[clinic input]
3072os.ctermid
3073
3074Return the name of the controlling terminal for this process.
3075[clinic start generated code]*/
3076
Larry Hastings2f936352014-08-05 14:04:04 +10003077static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003078os_ctermid_impl(PyObject *module)
3079/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003080{
Victor Stinner8c62be82010-05-06 00:08:46 +00003081 char *ret;
3082 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003083
Greg Wardb48bc172000-03-01 21:51:56 +00003084#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00003085 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003086#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003087 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003088#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003089 if (ret == NULL)
3090 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00003091 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003092}
Larry Hastings2f936352014-08-05 14:04:04 +10003093#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003094
Larry Hastings2f936352014-08-05 14:04:04 +10003095
3096/*[clinic input]
3097os.chdir
3098
3099 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
3100
3101Change the current working directory to the specified path.
3102
3103path may always be specified as a string.
3104On some platforms, path may also be specified as an open file descriptor.
3105 If this functionality is unavailable, using it raises an exception.
3106[clinic start generated code]*/
3107
Larry Hastings2f936352014-08-05 14:04:04 +10003108static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003109os_chdir_impl(PyObject *module, path_t *path)
3110/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003111{
3112 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003113
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003114 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
3115 return NULL;
3116 }
3117
Larry Hastings9cf065c2012-06-22 16:30:09 -07003118 Py_BEGIN_ALLOW_THREADS
3119#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003120 /* on unix, success = 0, on windows, success = !0 */
3121 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003122#else
3123#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10003124 if (path->fd != -1)
3125 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003126 else
3127#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003128 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003129#endif
3130 Py_END_ALLOW_THREADS
3131
3132 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003133 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003134 }
3135
Larry Hastings2f936352014-08-05 14:04:04 +10003136 Py_RETURN_NONE;
3137}
3138
3139
3140#ifdef HAVE_FCHDIR
3141/*[clinic input]
3142os.fchdir
3143
3144 fd: fildes
3145
3146Change to the directory of the given file descriptor.
3147
3148fd must be opened on a directory, not a file.
3149Equivalent to os.chdir(fd).
3150
3151[clinic start generated code]*/
3152
Fred Drake4d1e64b2002-04-15 19:40:07 +00003153static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003154os_fchdir_impl(PyObject *module, int fd)
3155/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00003156{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003157 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
3158 return NULL;
3159 }
Larry Hastings2f936352014-08-05 14:04:04 +10003160 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00003161}
3162#endif /* HAVE_FCHDIR */
3163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003164
Larry Hastings2f936352014-08-05 14:04:04 +10003165/*[clinic input]
3166os.chmod
3167
3168 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00003169 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10003170 On some platforms, path may also be specified as an open file descriptor.
3171 If this functionality is unavailable, using it raises an exception.
3172
3173 mode: int
3174 Operating-system mode bitfield.
3175
3176 *
3177
3178 dir_fd : dir_fd(requires='fchmodat') = None
3179 If not None, it should be a file descriptor open to a directory,
3180 and path should be relative; path will then be relative to that
3181 directory.
3182
3183 follow_symlinks: bool = True
3184 If False, and the last element of the path is a symbolic link,
3185 chmod will modify the symbolic link itself instead of the file
3186 the link points to.
3187
3188Change the access permissions of a file.
3189
3190It is an error to use dir_fd or follow_symlinks when specifying path as
3191 an open file descriptor.
3192dir_fd and follow_symlinks may not be implemented on your platform.
3193 If they are unavailable, using them will raise a NotImplementedError.
3194
3195[clinic start generated code]*/
3196
Larry Hastings2f936352014-08-05 14:04:04 +10003197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003198os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003199 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003200/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003201{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003202 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003203
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003204#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003205 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003206#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003207
Larry Hastings9cf065c2012-06-22 16:30:09 -07003208#ifdef HAVE_FCHMODAT
3209 int fchmodat_nofollow_unsupported = 0;
Ronald Oussoren41761932020-11-08 10:05:27 +01003210 int fchmodat_unsupported = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003211#endif
3212
Larry Hastings9cf065c2012-06-22 16:30:09 -07003213#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3214 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003215 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003216#endif
3217
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003218 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3219 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3220 return NULL;
3221 }
3222
Larry Hastings9cf065c2012-06-22 16:30:09 -07003223#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003224 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003225 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003226 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003227 result = 0;
3228 else {
3229 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003230 attr &= ~FILE_ATTRIBUTE_READONLY;
3231 else
3232 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003233 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003234 }
3235 Py_END_ALLOW_THREADS
3236
3237 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003238 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003239 }
3240#else /* MS_WINDOWS */
3241 Py_BEGIN_ALLOW_THREADS
3242#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003243 if (path->fd != -1)
3244 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003245 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003246#endif /* HAVE_CHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003247#ifdef HAVE_LCHMOD
3248 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003249 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003251#endif /* HAVE_LCHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003252#ifdef HAVE_FCHMODAT
3253 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
Ronald Oussoren41761932020-11-08 10:05:27 +01003254 if (HAVE_FCHMODAT_RUNTIME) {
3255 /*
3256 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3257 * The documentation specifically shows how to use it,
3258 * and then says it isn't implemented yet.
3259 * (true on linux with glibc 2.15, and openindiana 3.x)
3260 *
3261 * Once it is supported, os.chmod will automatically
3262 * support dir_fd and follow_symlinks=False. (Hopefully.)
3263 * Until then, we need to be careful what exception we raise.
3264 */
3265 result = fchmodat(dir_fd, path->narrow, mode,
3266 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3267 /*
3268 * But wait! We can't throw the exception without allowing threads,
3269 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3270 */
3271 fchmodat_nofollow_unsupported =
3272 result &&
3273 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3274 !follow_symlinks;
3275 } else {
3276 fchmodat_unsupported = 1;
3277 fchmodat_nofollow_unsupported = 1;
3278
3279 result = -1;
3280 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003281 }
3282 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003283#endif /* HAVE_FHCMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003284 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003285 Py_END_ALLOW_THREADS
3286
3287 if (result) {
3288#ifdef HAVE_FCHMODAT
Ronald Oussoren41761932020-11-08 10:05:27 +01003289 if (fchmodat_unsupported) {
3290 if (dir_fd != DEFAULT_DIR_FD) {
3291 argument_unavailable_error("chmod", "dir_fd");
3292 return NULL;
3293 }
3294 }
3295
Larry Hastings9cf065c2012-06-22 16:30:09 -07003296 if (fchmodat_nofollow_unsupported) {
3297 if (dir_fd != DEFAULT_DIR_FD)
3298 dir_fd_and_follow_symlinks_invalid("chmod",
3299 dir_fd, follow_symlinks);
3300 else
3301 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003302 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003303 }
3304 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003305#endif /* HAVE_FCHMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003306 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003307 }
Ronald Oussoren41761932020-11-08 10:05:27 +01003308#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003309
Larry Hastings2f936352014-08-05 14:04:04 +10003310 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003311}
3312
Larry Hastings9cf065c2012-06-22 16:30:09 -07003313
Christian Heimes4e30a842007-11-30 22:12:06 +00003314#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003315/*[clinic input]
3316os.fchmod
3317
3318 fd: int
3319 mode: int
3320
3321Change the access permissions of the file given by file descriptor fd.
3322
3323Equivalent to os.chmod(fd, mode).
3324[clinic start generated code]*/
3325
Larry Hastings2f936352014-08-05 14:04:04 +10003326static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003327os_fchmod_impl(PyObject *module, int fd, int mode)
3328/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003329{
3330 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003331 int async_err = 0;
3332
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003333 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3334 return NULL;
3335 }
3336
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003337 do {
3338 Py_BEGIN_ALLOW_THREADS
3339 res = fchmod(fd, mode);
3340 Py_END_ALLOW_THREADS
3341 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3342 if (res != 0)
3343 return (!async_err) ? posix_error() : NULL;
3344
Victor Stinner8c62be82010-05-06 00:08:46 +00003345 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003346}
3347#endif /* HAVE_FCHMOD */
3348
Larry Hastings2f936352014-08-05 14:04:04 +10003349
Christian Heimes4e30a842007-11-30 22:12:06 +00003350#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003351/*[clinic input]
3352os.lchmod
3353
3354 path: path_t
3355 mode: int
3356
3357Change the access permissions of a file, without following symbolic links.
3358
3359If path is a symlink, this affects the link itself rather than the target.
3360Equivalent to chmod(path, mode, follow_symlinks=False)."
3361[clinic start generated code]*/
3362
Larry Hastings2f936352014-08-05 14:04:04 +10003363static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003364os_lchmod_impl(PyObject *module, path_t *path, int mode)
3365/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003366{
Victor Stinner8c62be82010-05-06 00:08:46 +00003367 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003368 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3369 return NULL;
3370 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003371 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003372 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003373 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003374 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003375 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003376 return NULL;
3377 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003378 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003379}
3380#endif /* HAVE_LCHMOD */
3381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003382
Thomas Wouterscf297e42007-02-23 15:07:44 +00003383#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003384/*[clinic input]
3385os.chflags
3386
3387 path: path_t
3388 flags: unsigned_long(bitwise=True)
3389 follow_symlinks: bool=True
3390
3391Set file flags.
3392
3393If follow_symlinks is False, and the last element of the path is a symbolic
3394 link, chflags will change flags on the symbolic link itself instead of the
3395 file the link points to.
3396follow_symlinks may not be implemented on your platform. If it is
3397unavailable, using it will raise a NotImplementedError.
3398
3399[clinic start generated code]*/
3400
Larry Hastings2f936352014-08-05 14:04:04 +10003401static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003402os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003403 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003404/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003405{
3406 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003407
3408#ifndef HAVE_LCHFLAGS
3409 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003410 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411#endif
3412
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003413 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3414 return NULL;
3415 }
3416
Victor Stinner8c62be82010-05-06 00:08:46 +00003417 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003418#ifdef HAVE_LCHFLAGS
3419 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003420 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003421 else
3422#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003423 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003424 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425
Larry Hastings2f936352014-08-05 14:04:04 +10003426 if (result)
3427 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428
Larry Hastings2f936352014-08-05 14:04:04 +10003429 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003430}
3431#endif /* HAVE_CHFLAGS */
3432
Larry Hastings2f936352014-08-05 14:04:04 +10003433
Thomas Wouterscf297e42007-02-23 15:07:44 +00003434#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003435/*[clinic input]
3436os.lchflags
3437
3438 path: path_t
3439 flags: unsigned_long(bitwise=True)
3440
3441Set file flags.
3442
3443This function will not follow symbolic links.
3444Equivalent to chflags(path, flags, follow_symlinks=False).
3445[clinic start generated code]*/
3446
Larry Hastings2f936352014-08-05 14:04:04 +10003447static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003448os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3449/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003450{
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003452 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3453 return NULL;
3454 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003455 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003456 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003457 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003458 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003459 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003460 }
Victor Stinner292c8352012-10-30 02:17:38 +01003461 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003462}
3463#endif /* HAVE_LCHFLAGS */
3464
Larry Hastings2f936352014-08-05 14:04:04 +10003465
Martin v. Löwis244edc82001-10-04 22:44:26 +00003466#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003467/*[clinic input]
3468os.chroot
3469 path: path_t
3470
3471Change root directory to path.
3472
3473[clinic start generated code]*/
3474
Larry Hastings2f936352014-08-05 14:04:04 +10003475static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003476os_chroot_impl(PyObject *module, path_t *path)
3477/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003478{
3479 int res;
3480 Py_BEGIN_ALLOW_THREADS
3481 res = chroot(path->narrow);
3482 Py_END_ALLOW_THREADS
3483 if (res < 0)
3484 return path_error(path);
3485 Py_RETURN_NONE;
3486}
3487#endif /* HAVE_CHROOT */
3488
Martin v. Löwis244edc82001-10-04 22:44:26 +00003489
Guido van Rossum21142a01999-01-08 21:05:37 +00003490#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003491/*[clinic input]
3492os.fsync
3493
3494 fd: fildes
3495
3496Force write of fd to disk.
3497[clinic start generated code]*/
3498
Larry Hastings2f936352014-08-05 14:04:04 +10003499static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003500os_fsync_impl(PyObject *module, int fd)
3501/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003502{
3503 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003504}
3505#endif /* HAVE_FSYNC */
3506
Larry Hastings2f936352014-08-05 14:04:04 +10003507
Ross Lagerwall7807c352011-03-17 20:20:30 +02003508#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003509/*[clinic input]
3510os.sync
3511
3512Force write of everything to disk.
3513[clinic start generated code]*/
3514
Larry Hastings2f936352014-08-05 14:04:04 +10003515static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003516os_sync_impl(PyObject *module)
3517/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003518{
3519 Py_BEGIN_ALLOW_THREADS
3520 sync();
3521 Py_END_ALLOW_THREADS
3522 Py_RETURN_NONE;
3523}
Larry Hastings2f936352014-08-05 14:04:04 +10003524#endif /* HAVE_SYNC */
3525
Ross Lagerwall7807c352011-03-17 20:20:30 +02003526
Guido van Rossum21142a01999-01-08 21:05:37 +00003527#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003528#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003529extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3530#endif
3531
Larry Hastings2f936352014-08-05 14:04:04 +10003532/*[clinic input]
3533os.fdatasync
3534
3535 fd: fildes
3536
3537Force write of fd to disk without forcing update of metadata.
3538[clinic start generated code]*/
3539
Larry Hastings2f936352014-08-05 14:04:04 +10003540static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003541os_fdatasync_impl(PyObject *module, int fd)
3542/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003543{
3544 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003545}
3546#endif /* HAVE_FDATASYNC */
3547
3548
Fredrik Lundh10723342000-07-10 16:38:09 +00003549#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003550/*[clinic input]
3551os.chown
3552
3553 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003554 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003555
3556 uid: uid_t
3557
3558 gid: gid_t
3559
3560 *
3561
3562 dir_fd : dir_fd(requires='fchownat') = None
3563 If not None, it should be a file descriptor open to a directory,
3564 and path should be relative; path will then be relative to that
3565 directory.
3566
3567 follow_symlinks: bool = True
3568 If False, and the last element of the path is a symbolic link,
3569 stat will examine the symbolic link itself instead of the file
3570 the link points to.
3571
3572Change the owner and group id of path to the numeric uid and gid.\
3573
3574path may always be specified as a string.
3575On some platforms, path may also be specified as an open file descriptor.
3576 If this functionality is unavailable, using it raises an exception.
3577If dir_fd is not None, it should be a file descriptor open to a directory,
3578 and path should be relative; path will then be relative to that directory.
3579If follow_symlinks is False, and the last element of the path is a symbolic
3580 link, chown will modify the symbolic link itself instead of the file the
3581 link points to.
3582It is an error to use dir_fd or follow_symlinks when specifying path as
3583 an open file descriptor.
3584dir_fd and follow_symlinks may not be implemented on your platform.
3585 If they are unavailable, using them will raise a NotImplementedError.
3586
3587[clinic start generated code]*/
3588
Larry Hastings2f936352014-08-05 14:04:04 +10003589static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003590os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003591 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003592/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003593{
3594 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003595
Ronald Oussoren41761932020-11-08 10:05:27 +01003596#if defined(HAVE_FCHOWNAT)
3597 int fchownat_unsupported = 0;
3598#endif
3599
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3601 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003602 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003603#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003604 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3605 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3606 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003607
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003608 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3609 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3610 return NULL;
3611 }
3612
Victor Stinner8c62be82010-05-06 00:08:46 +00003613 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003614#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003615 if (path->fd != -1)
3616 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003617 else
3618#endif
3619#ifdef HAVE_LCHOWN
3620 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003621 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003622 else
3623#endif
3624#ifdef HAVE_FCHOWNAT
Ronald Oussoren41761932020-11-08 10:05:27 +01003625 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
3626 if (HAVE_FCHOWNAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10003627 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +01003629 } else {
3630 fchownat_unsupported = 1;
3631 }
3632 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003633#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003634 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636
Ronald Oussoren41761932020-11-08 10:05:27 +01003637#ifdef HAVE_FCHOWNAT
3638 if (fchownat_unsupported) {
3639 /* This would be incorrect if the current platform
3640 * doesn't support lchown.
3641 */
3642 argument_unavailable_error(NULL, "dir_fd");
3643 return NULL;
3644 }
3645#endif
3646
Larry Hastings2f936352014-08-05 14:04:04 +10003647 if (result)
3648 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003649
Larry Hastings2f936352014-08-05 14:04:04 +10003650 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003651}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003652#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003653
Larry Hastings2f936352014-08-05 14:04:04 +10003654
Christian Heimes4e30a842007-11-30 22:12:06 +00003655#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003656/*[clinic input]
3657os.fchown
3658
3659 fd: int
3660 uid: uid_t
3661 gid: gid_t
3662
3663Change the owner and group id of the file specified by file descriptor.
3664
3665Equivalent to os.chown(fd, uid, gid).
3666
3667[clinic start generated code]*/
3668
Larry Hastings2f936352014-08-05 14:04:04 +10003669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003670os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3671/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003672{
Victor Stinner8c62be82010-05-06 00:08:46 +00003673 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003674 int async_err = 0;
3675
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003676 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3677 return NULL;
3678 }
3679
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003680 do {
3681 Py_BEGIN_ALLOW_THREADS
3682 res = fchown(fd, uid, gid);
3683 Py_END_ALLOW_THREADS
3684 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3685 if (res != 0)
3686 return (!async_err) ? posix_error() : NULL;
3687
Victor Stinner8c62be82010-05-06 00:08:46 +00003688 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003689}
3690#endif /* HAVE_FCHOWN */
3691
Larry Hastings2f936352014-08-05 14:04:04 +10003692
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003693#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003694/*[clinic input]
3695os.lchown
3696
3697 path : path_t
3698 uid: uid_t
3699 gid: gid_t
3700
3701Change the owner and group id of path to the numeric uid and gid.
3702
3703This function will not follow symbolic links.
3704Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3705[clinic start generated code]*/
3706
Larry Hastings2f936352014-08-05 14:04:04 +10003707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003708os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3709/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003710{
Victor Stinner8c62be82010-05-06 00:08:46 +00003711 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003712 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3713 return NULL;
3714 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003715 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003716 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003717 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003718 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003719 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003720 }
Larry Hastings2f936352014-08-05 14:04:04 +10003721 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003722}
3723#endif /* HAVE_LCHOWN */
3724
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003725
Barry Warsaw53699e91996-12-10 23:23:01 +00003726static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003727posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003728{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003729#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003730 wchar_t wbuf[MAXPATHLEN];
3731 wchar_t *wbuf2 = wbuf;
3732 DWORD len;
3733
3734 Py_BEGIN_ALLOW_THREADS
3735 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3736 /* If the buffer is large enough, len does not include the
3737 terminating \0. If the buffer is too small, len includes
3738 the space needed for the terminator. */
3739 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003740 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003741 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003742 }
Victor Stinner689830e2019-06-26 17:31:12 +02003743 else {
3744 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003745 }
Victor Stinner689830e2019-06-26 17:31:12 +02003746 if (wbuf2) {
3747 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003748 }
Victor Stinner689830e2019-06-26 17:31:12 +02003749 }
3750 Py_END_ALLOW_THREADS
3751
3752 if (!wbuf2) {
3753 PyErr_NoMemory();
3754 return NULL;
3755 }
3756 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003757 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003758 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003759 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003760 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003761
Victor Stinner689830e2019-06-26 17:31:12 +02003762 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3763 if (wbuf2 != wbuf) {
3764 PyMem_RawFree(wbuf2);
3765 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003766
Victor Stinner689830e2019-06-26 17:31:12 +02003767 if (use_bytes) {
3768 if (resobj == NULL) {
3769 return NULL;
3770 }
3771 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3772 }
3773
3774 return resobj;
3775#else
3776 const size_t chunk = 1024;
3777
3778 char *buf = NULL;
3779 char *cwd = NULL;
3780 size_t buflen = 0;
3781
Victor Stinner8c62be82010-05-06 00:08:46 +00003782 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003783 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003784 char *newbuf;
3785 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3786 buflen += chunk;
3787 newbuf = PyMem_RawRealloc(buf, buflen);
3788 }
3789 else {
3790 newbuf = NULL;
3791 }
3792 if (newbuf == NULL) {
3793 PyMem_RawFree(buf);
3794 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003795 break;
3796 }
Victor Stinner689830e2019-06-26 17:31:12 +02003797 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003798
Victor Stinner4403d7d2015-04-25 00:16:10 +02003799 cwd = getcwd(buf, buflen);
3800 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003802
Victor Stinner689830e2019-06-26 17:31:12 +02003803 if (buf == NULL) {
3804 return PyErr_NoMemory();
3805 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003806 if (cwd == NULL) {
3807 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003808 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003809 }
3810
Victor Stinner689830e2019-06-26 17:31:12 +02003811 PyObject *obj;
3812 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003813 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003814 }
3815 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003816 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003817 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003818 PyMem_RawFree(buf);
3819
3820 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003821#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003822}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003823
Larry Hastings2f936352014-08-05 14:04:04 +10003824
3825/*[clinic input]
3826os.getcwd
3827
3828Return a unicode string representing the current working directory.
3829[clinic start generated code]*/
3830
Larry Hastings2f936352014-08-05 14:04:04 +10003831static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003832os_getcwd_impl(PyObject *module)
3833/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003834{
3835 return posix_getcwd(0);
3836}
3837
Larry Hastings2f936352014-08-05 14:04:04 +10003838
3839/*[clinic input]
3840os.getcwdb
3841
3842Return a bytes string representing the current working directory.
3843[clinic start generated code]*/
3844
Larry Hastings2f936352014-08-05 14:04:04 +10003845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003846os_getcwdb_impl(PyObject *module)
3847/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003848{
3849 return posix_getcwd(1);
3850}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003851
Larry Hastings2f936352014-08-05 14:04:04 +10003852
Larry Hastings9cf065c2012-06-22 16:30:09 -07003853#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3854#define HAVE_LINK 1
3855#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003856
Guido van Rossumb6775db1994-08-01 11:34:53 +00003857#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003858/*[clinic input]
3859
3860os.link
3861
3862 src : path_t
3863 dst : path_t
3864 *
3865 src_dir_fd : dir_fd = None
3866 dst_dir_fd : dir_fd = None
3867 follow_symlinks: bool = True
3868
3869Create a hard link to a file.
3870
3871If either src_dir_fd or dst_dir_fd is not None, it should be a file
3872 descriptor open to a directory, and the respective path string (src or dst)
3873 should be relative; the path will then be relative to that directory.
3874If follow_symlinks is False, and the last element of src is a symbolic
3875 link, link will create a link to the symbolic link itself instead of the
3876 file the link points to.
3877src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3878 platform. If they are unavailable, using them will raise a
3879 NotImplementedError.
3880[clinic start generated code]*/
3881
Larry Hastings2f936352014-08-05 14:04:04 +10003882static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003883os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003884 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003885/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003886{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003887#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003888 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003889#else
3890 int result;
3891#endif
Ronald Oussoren41761932020-11-08 10:05:27 +01003892#if defined(HAVE_LINKAT)
3893 int linkat_unavailable = 0;
3894#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003895
Larry Hastings9cf065c2012-06-22 16:30:09 -07003896#ifndef HAVE_LINKAT
3897 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3898 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003899 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003900 }
3901#endif
3902
Steve Dowercc16be82016-09-08 10:35:16 -07003903#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003904 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003905 PyErr_SetString(PyExc_NotImplementedError,
3906 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003907 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003908 }
Steve Dowercc16be82016-09-08 10:35:16 -07003909#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003910
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003911 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3912 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3913 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3914 return NULL;
3915 }
3916
Brian Curtin1b9df392010-11-24 20:24:31 +00003917#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003918 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003919 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003920 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003921
Larry Hastings2f936352014-08-05 14:04:04 +10003922 if (!result)
3923 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003924#else
3925 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003926#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003927 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3928 (dst_dir_fd != DEFAULT_DIR_FD) ||
Ronald Oussoren41761932020-11-08 10:05:27 +01003929 (!follow_symlinks)) {
3930
3931 if (HAVE_LINKAT_RUNTIME) {
3932
3933 result = linkat(src_dir_fd, src->narrow,
3934 dst_dir_fd, dst->narrow,
3935 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3936
3937 }
3938#ifdef __APPLE__
3939 else {
3940 if (src_dir_fd == DEFAULT_DIR_FD && dst_dir_fd == DEFAULT_DIR_FD) {
3941 /* See issue 41355: This matches the behaviour of !HAVE_LINKAT */
3942 result = link(src->narrow, dst->narrow);
3943 } else {
3944 linkat_unavailable = 1;
3945 }
3946 }
3947#endif
3948 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003949 else
Steve Dowercc16be82016-09-08 10:35:16 -07003950#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003951 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003952 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003953
Ronald Oussoren41761932020-11-08 10:05:27 +01003954#ifdef HAVE_LINKAT
3955 if (linkat_unavailable) {
3956 /* Either or both dir_fd arguments were specified */
3957 if (src_dir_fd != DEFAULT_DIR_FD) {
3958 argument_unavailable_error("link", "src_dir_fd");
3959 } else {
3960 argument_unavailable_error("link", "dst_dir_fd");
3961 }
3962 return NULL;
3963 }
3964#endif
3965
Larry Hastings2f936352014-08-05 14:04:04 +10003966 if (result)
3967 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003968#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003969
Larry Hastings2f936352014-08-05 14:04:04 +10003970 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003971}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003972#endif
3973
Brian Curtin1b9df392010-11-24 20:24:31 +00003974
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003975#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003976static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003977_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003978{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003979 PyObject *v;
3980 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3981 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003982 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003983 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003984 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003985 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003986
Steve Dowercc16be82016-09-08 10:35:16 -07003987 WIN32_FIND_DATAW wFileData;
3988 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003989
Steve Dowercc16be82016-09-08 10:35:16 -07003990 if (!path->wide) { /* Default arg: "." */
3991 po_wchars = L".";
3992 len = 1;
3993 } else {
3994 po_wchars = path->wide;
3995 len = wcslen(path->wide);
3996 }
3997 /* The +5 is so we can append "\\*.*\0" */
3998 wnamebuf = PyMem_New(wchar_t, len + 5);
3999 if (!wnamebuf) {
4000 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07004001 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004002 }
Steve Dowercc16be82016-09-08 10:35:16 -07004003 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07004005 wchar_t wch = wnamebuf[len-1];
4006 if (wch != SEP && wch != ALTSEP && wch != L':')
4007 wnamebuf[len++] = SEP;
4008 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00004009 }
Steve Dowercc16be82016-09-08 10:35:16 -07004010 if ((list = PyList_New(0)) == NULL) {
4011 goto exit;
4012 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00004013 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004014 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00004015 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 if (hFindFile == INVALID_HANDLE_VALUE) {
4017 int error = GetLastError();
4018 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004019 goto exit;
4020 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004021 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004022 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004023 }
4024 do {
4025 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07004026 if (wcscmp(wFileData.cFileName, L".") != 0 &&
4027 wcscmp(wFileData.cFileName, L"..") != 0) {
4028 v = PyUnicode_FromWideChar(wFileData.cFileName,
4029 wcslen(wFileData.cFileName));
4030 if (path->narrow && v) {
4031 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
4032 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004033 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004034 Py_DECREF(list);
4035 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004036 break;
4037 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004038 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004039 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004040 Py_DECREF(list);
4041 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004042 break;
4043 }
4044 Py_DECREF(v);
4045 }
4046 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004047 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00004048 Py_END_ALLOW_THREADS
4049 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4050 it got to the end of the directory. */
4051 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004052 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004053 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004054 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004055 }
4056 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004057
Larry Hastings9cf065c2012-06-22 16:30:09 -07004058exit:
4059 if (hFindFile != INVALID_HANDLE_VALUE) {
4060 if (FindClose(hFindFile) == FALSE) {
4061 if (list != NULL) {
4062 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004063 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004064 }
4065 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004066 }
Victor Stinnerb6404912013-07-07 16:21:41 +02004067 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004068
Larry Hastings9cf065c2012-06-22 16:30:09 -07004069 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004070} /* end of _listdir_windows_no_opendir */
4071
4072#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
4073
4074static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004075_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004076{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004077 PyObject *v;
4078 DIR *dirp = NULL;
4079 struct dirent *ep;
4080 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004081#ifdef HAVE_FDOPENDIR
4082 int fd = -1;
4083#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004084
Victor Stinner8c62be82010-05-06 00:08:46 +00004085 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004086#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07004087 if (path->fd != -1) {
Ronald Oussoren41761932020-11-08 10:05:27 +01004088 if (HAVE_FDOPENDIR_RUNTIME) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004089 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02004090 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01004091 if (fd == -1)
4092 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004093
Larry Hastingsfdaea062012-06-25 04:42:23 -07004094 return_str = 1;
4095
Larry Hastings9cf065c2012-06-22 16:30:09 -07004096 Py_BEGIN_ALLOW_THREADS
4097 dirp = fdopendir(fd);
4098 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01004099 } else {
4100 PyErr_SetString(PyExc_TypeError,
4101 "listdir: path should be string, bytes, os.PathLike or None, not int");
4102 return NULL;
4103 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004104 }
4105 else
4106#endif
4107 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004108 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07004109 if (path->narrow) {
4110 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03004111 /* only return bytes if they specified a bytes-like object */
4112 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07004113 }
4114 else {
4115 name = ".";
4116 return_str = 1;
4117 }
4118
Larry Hastings9cf065c2012-06-22 16:30:09 -07004119 Py_BEGIN_ALLOW_THREADS
4120 dirp = opendir(name);
4121 Py_END_ALLOW_THREADS
4122 }
4123
4124 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07004125 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004126#ifdef HAVE_FDOPENDIR
4127 if (fd != -1) {
4128 Py_BEGIN_ALLOW_THREADS
4129 close(fd);
4130 Py_END_ALLOW_THREADS
4131 }
4132#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004133 goto exit;
4134 }
4135 if ((list = PyList_New(0)) == NULL) {
4136 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004137 }
4138 for (;;) {
4139 errno = 0;
4140 Py_BEGIN_ALLOW_THREADS
4141 ep = readdir(dirp);
4142 Py_END_ALLOW_THREADS
4143 if (ep == NULL) {
4144 if (errno == 0) {
4145 break;
4146 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004147 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004148 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004149 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004150 }
4151 }
4152 if (ep->d_name[0] == '.' &&
4153 (NAMLEN(ep) == 1 ||
4154 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
4155 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07004156 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00004157 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
4158 else
4159 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00004160 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004161 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004162 break;
4163 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004164 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004165 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004166 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004167 break;
4168 }
4169 Py_DECREF(v);
4170 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00004171
Larry Hastings9cf065c2012-06-22 16:30:09 -07004172exit:
4173 if (dirp != NULL) {
4174 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004175#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07004176 if (fd > -1)
4177 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004178#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004179 closedir(dirp);
4180 Py_END_ALLOW_THREADS
4181 }
4182
Larry Hastings9cf065c2012-06-22 16:30:09 -07004183 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004184} /* end of _posix_listdir */
4185#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004186
Larry Hastings2f936352014-08-05 14:04:04 +10004187
4188/*[clinic input]
4189os.listdir
4190
4191 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
4192
4193Return a list containing the names of the files in the directory.
4194
BNMetricsb9427072018-11-02 15:20:19 +00004195path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10004196 the filenames returned will also be bytes; in all other circumstances
4197 the filenames returned will be str.
4198If path is None, uses the path='.'.
4199On some platforms, path may also be specified as an open file descriptor;\
4200 the file descriptor must refer to a directory.
4201 If this functionality is unavailable, using it raises NotImplementedError.
4202
4203The list is in arbitrary order. It does not include the special
4204entries '.' and '..' even if they are present in the directory.
4205
4206
4207[clinic start generated code]*/
4208
Larry Hastings2f936352014-08-05 14:04:04 +10004209static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004210os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00004211/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004212{
Steve Dower60419a72019-06-24 08:42:54 -07004213 if (PySys_Audit("os.listdir", "O",
4214 path->object ? path->object : Py_None) < 0) {
4215 return NULL;
4216 }
Larry Hastings2f936352014-08-05 14:04:04 +10004217#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4218 return _listdir_windows_no_opendir(path, NULL);
4219#else
4220 return _posix_listdir(path, NULL);
4221#endif
4222}
4223
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004224#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00004225/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004226/*[clinic input]
4227os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02004228
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004229 path: path_t
4230 /
4231
4232[clinic start generated code]*/
4233
4234static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004235os__getfullpathname_impl(PyObject *module, path_t *path)
4236/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004237{
Victor Stinner3939c322019-06-25 15:02:43 +02004238 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004239
Victor Stinner3939c322019-06-25 15:02:43 +02004240 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
4241 if (_Py_abspath(path->wide, &abspath) < 0) {
4242 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00004243 }
Victor Stinner3939c322019-06-25 15:02:43 +02004244 if (abspath == NULL) {
4245 return PyErr_NoMemory();
4246 }
4247
4248 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
4249 PyMem_RawFree(abspath);
4250 if (str == NULL) {
4251 return NULL;
4252 }
4253 if (path->narrow) {
4254 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
4255 }
4256 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10004257}
Brian Curtind40e6f72010-07-08 21:39:08 +00004258
Brian Curtind25aef52011-06-13 15:16:04 -05004259
Larry Hastings2f936352014-08-05 14:04:04 +10004260/*[clinic input]
4261os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004262
Steve Dower23ad6d02018-02-22 10:39:10 -08004263 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004264 /
4265
4266A helper function for samepath on windows.
4267[clinic start generated code]*/
4268
Larry Hastings2f936352014-08-05 14:04:04 +10004269static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004270os__getfinalpathname_impl(PyObject *module, path_t *path)
4271/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004272{
4273 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004274 wchar_t buf[MAXPATHLEN], *target_path = buf;
4275 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004276 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004277 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004278
Steve Dower23ad6d02018-02-22 10:39:10 -08004279 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004280 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004281 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004282 0, /* desired access */
4283 0, /* share mode */
4284 NULL, /* security attributes */
4285 OPEN_EXISTING,
4286 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4287 FILE_FLAG_BACKUP_SEMANTICS,
4288 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004289 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004290
Steve Dower23ad6d02018-02-22 10:39:10 -08004291 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004292 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004293 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004294
4295 /* We have a good handle to the target, use it to determine the
4296 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004297 while (1) {
4298 Py_BEGIN_ALLOW_THREADS
4299 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4300 buf_size, VOLUME_NAME_DOS);
4301 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004302
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004303 if (!result_length) {
4304 result = win32_error_object("GetFinalPathNameByHandleW",
4305 path->object);
4306 goto cleanup;
4307 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004308
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004309 if (result_length < buf_size) {
4310 break;
4311 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004312
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004313 wchar_t *tmp;
4314 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4315 result_length * sizeof(*tmp));
4316 if (!tmp) {
4317 result = PyErr_NoMemory();
4318 goto cleanup;
4319 }
4320
4321 buf_size = result_length;
4322 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004323 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004324
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004325 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004326 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004327 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004328 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004329
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004330cleanup:
4331 if (target_path != buf) {
4332 PyMem_Free(target_path);
4333 }
4334 CloseHandle(hFile);
4335 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004336}
Brian Curtin62857742010-09-06 17:07:27 +00004337
Tim Golden6b528062013-08-01 12:44:00 +01004338
Larry Hastings2f936352014-08-05 14:04:04 +10004339/*[clinic input]
4340os._getvolumepathname
4341
Steve Dower23ad6d02018-02-22 10:39:10 -08004342 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004343
4344A helper function for ismount on Win32.
4345[clinic start generated code]*/
4346
Larry Hastings2f936352014-08-05 14:04:04 +10004347static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004348os__getvolumepathname_impl(PyObject *module, path_t *path)
4349/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004350{
4351 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004352 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004353 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004354 BOOL ret;
4355
Tim Golden6b528062013-08-01 12:44:00 +01004356 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004357 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004358
Victor Stinner850a18e2017-10-24 16:53:32 -07004359 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004360 PyErr_SetString(PyExc_OverflowError, "path too long");
4361 return NULL;
4362 }
4363
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004364 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004365 if (mountpath == NULL)
4366 return PyErr_NoMemory();
4367
4368 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004369 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004370 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004371 Py_END_ALLOW_THREADS
4372
4373 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004374 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004375 goto exit;
4376 }
4377 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004378 if (path->narrow)
4379 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004380
4381exit:
4382 PyMem_Free(mountpath);
4383 return result;
4384}
Tim Golden6b528062013-08-01 12:44:00 +01004385
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004386#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004387
Larry Hastings2f936352014-08-05 14:04:04 +10004388
4389/*[clinic input]
4390os.mkdir
4391
4392 path : path_t
4393
4394 mode: int = 0o777
4395
4396 *
4397
4398 dir_fd : dir_fd(requires='mkdirat') = None
4399
4400# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4401
4402Create a directory.
4403
4404If dir_fd is not None, it should be a file descriptor open to a directory,
4405 and path should be relative; path will then be relative to that directory.
4406dir_fd may not be implemented on your platform.
4407 If it is unavailable, using it will raise a NotImplementedError.
4408
4409The mode argument is ignored on Windows.
4410[clinic start generated code]*/
4411
Larry Hastings2f936352014-08-05 14:04:04 +10004412static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004413os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4414/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004415{
4416 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004417#ifdef HAVE_MKDIRAT
4418 int mkdirat_unavailable = 0;
4419#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004420
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004421 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4422 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4423 return NULL;
4424 }
4425
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004426#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004427 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004428 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004429 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004430
Larry Hastings2f936352014-08-05 14:04:04 +10004431 if (!result)
4432 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004433#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004434 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004435#if HAVE_MKDIRAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004436 if (dir_fd != DEFAULT_DIR_FD) {
4437 if (HAVE_MKDIRAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004438 result = mkdirat(dir_fd, path->narrow, mode);
Ronald Oussoren41761932020-11-08 10:05:27 +01004439
4440 } else {
4441 mkdirat_unavailable = 1;
4442 }
4443 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004445#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004446 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004447#else
Larry Hastings2f936352014-08-05 14:04:04 +10004448 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004449#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004450 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01004451
4452#if HAVE_MKDIRAT
4453 if (mkdirat_unavailable) {
4454 argument_unavailable_error(NULL, "dir_fd");
4455 return NULL;
4456 }
4457#endif
4458
Larry Hastings2f936352014-08-05 14:04:04 +10004459 if (result < 0)
4460 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004461#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004462 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004463}
4464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004465
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004466/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4467#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004468#include <sys/resource.h>
4469#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004470
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004471
4472#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004473/*[clinic input]
4474os.nice
4475
4476 increment: int
4477 /
4478
4479Add increment to the priority of process and return the new priority.
4480[clinic start generated code]*/
4481
Larry Hastings2f936352014-08-05 14:04:04 +10004482static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004483os_nice_impl(PyObject *module, int increment)
4484/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004485{
4486 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004487
Victor Stinner8c62be82010-05-06 00:08:46 +00004488 /* There are two flavours of 'nice': one that returns the new
4489 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004490 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004491 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004492
Victor Stinner8c62be82010-05-06 00:08:46 +00004493 If we are of the nice family that returns the new priority, we
4494 need to clear errno before the call, and check if errno is filled
4495 before calling posix_error() on a returnvalue of -1, because the
4496 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004497
Victor Stinner8c62be82010-05-06 00:08:46 +00004498 errno = 0;
4499 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004500#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004501 if (value == 0)
4502 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004503#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004504 if (value == -1 && errno != 0)
4505 /* either nice() or getpriority() returned an error */
4506 return posix_error();
4507 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004508}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004509#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004510
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004511
4512#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004513/*[clinic input]
4514os.getpriority
4515
4516 which: int
4517 who: int
4518
4519Return program scheduling priority.
4520[clinic start generated code]*/
4521
Larry Hastings2f936352014-08-05 14:04:04 +10004522static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004523os_getpriority_impl(PyObject *module, int which, int who)
4524/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004525{
4526 int retval;
4527
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004528 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004529 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004530 if (errno != 0)
4531 return posix_error();
4532 return PyLong_FromLong((long)retval);
4533}
4534#endif /* HAVE_GETPRIORITY */
4535
4536
4537#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004538/*[clinic input]
4539os.setpriority
4540
4541 which: int
4542 who: int
4543 priority: int
4544
4545Set program scheduling priority.
4546[clinic start generated code]*/
4547
Larry Hastings2f936352014-08-05 14:04:04 +10004548static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004549os_setpriority_impl(PyObject *module, int which, int who, int priority)
4550/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004551{
4552 int retval;
4553
4554 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004555 if (retval == -1)
4556 return posix_error();
4557 Py_RETURN_NONE;
4558}
4559#endif /* HAVE_SETPRIORITY */
4560
4561
Barry Warsaw53699e91996-12-10 23:23:01 +00004562static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004563internal_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 +00004564{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004565 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004566 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004567
Ronald Oussoren41761932020-11-08 10:05:27 +01004568#ifdef HAVE_RENAMEAT
4569 int renameat_unavailable = 0;
4570#endif
4571
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004572#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004573 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004574 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004575#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004576 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004577#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004578
Larry Hastings9cf065c2012-06-22 16:30:09 -07004579 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4580 (dst_dir_fd != DEFAULT_DIR_FD);
4581#ifndef HAVE_RENAMEAT
4582 if (dir_fd_specified) {
4583 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004584 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585 }
4586#endif
4587
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004588 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4589 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4590 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4591 return NULL;
4592 }
4593
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594#ifdef MS_WINDOWS
4595 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004596 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004597 Py_END_ALLOW_THREADS
4598
Larry Hastings2f936352014-08-05 14:04:04 +10004599 if (!result)
4600 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004601
4602#else
Steve Dowercc16be82016-09-08 10:35:16 -07004603 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4604 PyErr_Format(PyExc_ValueError,
4605 "%s: src and dst must be the same type", function_name);
4606 return NULL;
4607 }
4608
Larry Hastings9cf065c2012-06-22 16:30:09 -07004609 Py_BEGIN_ALLOW_THREADS
4610#ifdef HAVE_RENAMEAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004611 if (dir_fd_specified) {
4612 if (HAVE_RENAMEAT_RUNTIME) {
4613 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
4614 } else {
4615 renameat_unavailable = 1;
4616 }
4617 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004618#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004619 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004620 Py_END_ALLOW_THREADS
4621
Ronald Oussoren41761932020-11-08 10:05:27 +01004622
4623#ifdef HAVE_RENAMEAT
4624 if (renameat_unavailable) {
4625 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4626 return NULL;
4627 }
4628#endif
4629
Larry Hastings2f936352014-08-05 14:04:04 +10004630 if (result)
4631 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004633 Py_RETURN_NONE;
4634}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004635
Larry Hastings2f936352014-08-05 14:04:04 +10004636
4637/*[clinic input]
4638os.rename
4639
4640 src : path_t
4641 dst : path_t
4642 *
4643 src_dir_fd : dir_fd = None
4644 dst_dir_fd : dir_fd = None
4645
4646Rename a file or directory.
4647
4648If either src_dir_fd or dst_dir_fd is not None, it should be a file
4649 descriptor open to a directory, and the respective path string (src or dst)
4650 should be relative; the path will then be relative to that directory.
4651src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4652 If they are unavailable, using them will raise a NotImplementedError.
4653[clinic start generated code]*/
4654
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004656os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004657 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004658/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004659{
Larry Hastings2f936352014-08-05 14:04:04 +10004660 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004661}
4662
Larry Hastings2f936352014-08-05 14:04:04 +10004663
4664/*[clinic input]
4665os.replace = os.rename
4666
4667Rename a file or directory, overwriting the destination.
4668
4669If either src_dir_fd or dst_dir_fd is not None, it should be a file
4670 descriptor open to a directory, and the respective path string (src or dst)
4671 should be relative; the path will then be relative to that directory.
4672src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004673 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004674[clinic start generated code]*/
4675
Larry Hastings2f936352014-08-05 14:04:04 +10004676static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004677os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4678 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004679/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004680{
4681 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4682}
4683
4684
4685/*[clinic input]
4686os.rmdir
4687
4688 path: path_t
4689 *
4690 dir_fd: dir_fd(requires='unlinkat') = None
4691
4692Remove a directory.
4693
4694If dir_fd is not None, it should be a file descriptor open to a directory,
4695 and path should be relative; path will then be relative to that directory.
4696dir_fd may not be implemented on your platform.
4697 If it is unavailable, using it will raise a NotImplementedError.
4698[clinic start generated code]*/
4699
Larry Hastings2f936352014-08-05 14:04:04 +10004700static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004701os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4702/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004703{
4704 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004705#ifdef HAVE_UNLINKAT
4706 int unlinkat_unavailable = 0;
4707#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004708
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004709 if (PySys_Audit("os.rmdir", "Oi", path->object,
4710 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4711 return NULL;
4712 }
4713
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004714 Py_BEGIN_ALLOW_THREADS
4715#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004716 /* Windows, success=1, UNIX, success=0 */
4717 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004718#else
4719#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004720 if (dir_fd != DEFAULT_DIR_FD) {
4721 if (HAVE_UNLINKAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004722 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Ronald Oussoren41761932020-11-08 10:05:27 +01004723 } else {
4724 unlinkat_unavailable = 1;
4725 result = -1;
4726 }
4727 } else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004728#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004729 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004730#endif
4731 Py_END_ALLOW_THREADS
4732
Ronald Oussoren41761932020-11-08 10:05:27 +01004733#ifdef HAVE_UNLINKAT
4734 if (unlinkat_unavailable) {
4735 argument_unavailable_error("rmdir", "dir_fd");
4736 return NULL;
4737 }
4738#endif
4739
Larry Hastings2f936352014-08-05 14:04:04 +10004740 if (result)
4741 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004742
Larry Hastings2f936352014-08-05 14:04:04 +10004743 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004744}
4745
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004746
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004747#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004748#ifdef MS_WINDOWS
4749/*[clinic input]
4750os.system -> long
4751
4752 command: Py_UNICODE
4753
4754Execute the command in a subshell.
4755[clinic start generated code]*/
4756
Larry Hastings2f936352014-08-05 14:04:04 +10004757static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004758os_system_impl(PyObject *module, const Py_UNICODE *command)
4759/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004760{
4761 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004762
Steve Dowerfbe3c762019-10-18 00:52:15 -07004763 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004764 return -1;
4765 }
4766
Victor Stinner8c62be82010-05-06 00:08:46 +00004767 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004768 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004769 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004770 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004771 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004772 return result;
4773}
4774#else /* MS_WINDOWS */
4775/*[clinic input]
4776os.system -> long
4777
4778 command: FSConverter
4779
4780Execute the command in a subshell.
4781[clinic start generated code]*/
4782
Larry Hastings2f936352014-08-05 14:04:04 +10004783static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004784os_system_impl(PyObject *module, PyObject *command)
4785/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004786{
4787 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004788 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004789
Steve Dowerfbe3c762019-10-18 00:52:15 -07004790 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004791 return -1;
4792 }
4793
Larry Hastings2f936352014-08-05 14:04:04 +10004794 Py_BEGIN_ALLOW_THREADS
4795 result = system(bytes);
4796 Py_END_ALLOW_THREADS
4797 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004798}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004799#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004800#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004801
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004802
Larry Hastings2f936352014-08-05 14:04:04 +10004803/*[clinic input]
4804os.umask
4805
4806 mask: int
4807 /
4808
4809Set the current numeric umask and return the previous umask.
4810[clinic start generated code]*/
4811
Larry Hastings2f936352014-08-05 14:04:04 +10004812static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004813os_umask_impl(PyObject *module, int mask)
4814/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004815{
4816 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004817 if (i < 0)
4818 return posix_error();
4819 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004820}
4821
Brian Curtind40e6f72010-07-08 21:39:08 +00004822#ifdef MS_WINDOWS
4823
4824/* override the default DeleteFileW behavior so that directory
4825symlinks can be removed with this function, the same as with
4826Unix symlinks */
4827BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4828{
4829 WIN32_FILE_ATTRIBUTE_DATA info;
4830 WIN32_FIND_DATAW find_data;
4831 HANDLE find_data_handle;
4832 int is_directory = 0;
4833 int is_link = 0;
4834
4835 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4836 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004837
Brian Curtind40e6f72010-07-08 21:39:08 +00004838 /* Get WIN32_FIND_DATA structure for the path to determine if
4839 it is a symlink */
4840 if(is_directory &&
4841 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4842 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4843
4844 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004845 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4846 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4847 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4848 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004849 FindClose(find_data_handle);
4850 }
4851 }
4852 }
4853
4854 if (is_directory && is_link)
4855 return RemoveDirectoryW(lpFileName);
4856
4857 return DeleteFileW(lpFileName);
4858}
4859#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004861
Larry Hastings2f936352014-08-05 14:04:04 +10004862/*[clinic input]
4863os.unlink
4864
4865 path: path_t
4866 *
4867 dir_fd: dir_fd(requires='unlinkat')=None
4868
4869Remove a file (same as remove()).
4870
4871If dir_fd is not None, it should be a file descriptor open to a directory,
4872 and path should be relative; path will then be relative to that directory.
4873dir_fd may not be implemented on your platform.
4874 If it is unavailable, using it will raise a NotImplementedError.
4875
4876[clinic start generated code]*/
4877
Larry Hastings2f936352014-08-05 14:04:04 +10004878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004879os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4880/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004881{
4882 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004883#ifdef HAVE_UNLINKAT
4884 int unlinkat_unavailable = 0;
4885#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004886
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004887 if (PySys_Audit("os.remove", "Oi", path->object,
4888 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4889 return NULL;
4890 }
4891
Larry Hastings9cf065c2012-06-22 16:30:09 -07004892 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004893 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004894#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004895 /* Windows, success=1, UNIX, success=0 */
4896 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004897#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004898#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004899 if (dir_fd != DEFAULT_DIR_FD) {
4900 if (HAVE_UNLINKAT_RUNTIME) {
4901
Larry Hastings2f936352014-08-05 14:04:04 +10004902 result = unlinkat(dir_fd, path->narrow, 0);
Ronald Oussoren41761932020-11-08 10:05:27 +01004903 } else {
4904 unlinkat_unavailable = 1;
4905 }
4906 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004907#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004908 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004909#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004910 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004911 Py_END_ALLOW_THREADS
4912
Ronald Oussoren41761932020-11-08 10:05:27 +01004913#ifdef HAVE_UNLINKAT
4914 if (unlinkat_unavailable) {
4915 argument_unavailable_error(NULL, "dir_fd");
4916 return NULL;
4917 }
4918#endif
4919
Larry Hastings2f936352014-08-05 14:04:04 +10004920 if (result)
4921 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004922
Larry Hastings2f936352014-08-05 14:04:04 +10004923 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004924}
4925
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004926
Larry Hastings2f936352014-08-05 14:04:04 +10004927/*[clinic input]
4928os.remove = os.unlink
4929
4930Remove a file (same as unlink()).
4931
4932If dir_fd is not None, it should be a file descriptor open to a directory,
4933 and path should be relative; path will then be relative to that directory.
4934dir_fd may not be implemented on your platform.
4935 If it is unavailable, using it will raise a NotImplementedError.
4936[clinic start generated code]*/
4937
Larry Hastings2f936352014-08-05 14:04:04 +10004938static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004939os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4940/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004941{
4942 return os_unlink_impl(module, path, dir_fd);
4943}
4944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004945
Larry Hastings605a62d2012-06-24 04:33:36 -07004946static PyStructSequence_Field uname_result_fields[] = {
4947 {"sysname", "operating system name"},
4948 {"nodename", "name of machine on network (implementation-defined)"},
4949 {"release", "operating system release"},
4950 {"version", "operating system version"},
4951 {"machine", "hardware identifier"},
4952 {NULL}
4953};
4954
4955PyDoc_STRVAR(uname_result__doc__,
4956"uname_result: Result from os.uname().\n\n\
4957This object may be accessed either as a tuple of\n\
4958 (sysname, nodename, release, version, machine),\n\
4959or via the attributes sysname, nodename, release, version, and machine.\n\
4960\n\
4961See os.uname for more information.");
4962
4963static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08004964 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07004965 uname_result__doc__, /* doc */
4966 uname_result_fields,
4967 5
4968};
4969
Larry Hastings605a62d2012-06-24 04:33:36 -07004970#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004971/*[clinic input]
4972os.uname
4973
4974Return an object identifying the current operating system.
4975
4976The object behaves like a named tuple with the following fields:
4977 (sysname, nodename, release, version, machine)
4978
4979[clinic start generated code]*/
4980
Larry Hastings2f936352014-08-05 14:04:04 +10004981static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004982os_uname_impl(PyObject *module)
4983/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004984{
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 struct utsname u;
4986 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004987 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004988
Victor Stinner8c62be82010-05-06 00:08:46 +00004989 Py_BEGIN_ALLOW_THREADS
4990 res = uname(&u);
4991 Py_END_ALLOW_THREADS
4992 if (res < 0)
4993 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004994
Hai Shif707d942020-03-16 21:15:01 +08004995 PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08004996 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07004997 if (value == NULL)
4998 return NULL;
4999
5000#define SET(i, field) \
5001 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02005002 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07005003 if (!o) { \
5004 Py_DECREF(value); \
5005 return NULL; \
5006 } \
5007 PyStructSequence_SET_ITEM(value, i, o); \
5008 } \
5009
5010 SET(0, u.sysname);
5011 SET(1, u.nodename);
5012 SET(2, u.release);
5013 SET(3, u.version);
5014 SET(4, u.machine);
5015
5016#undef SET
5017
5018 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00005019}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005020#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005021
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005022
Larry Hastings9cf065c2012-06-22 16:30:09 -07005023
5024typedef struct {
5025 int now;
5026 time_t atime_s;
5027 long atime_ns;
5028 time_t mtime_s;
5029 long mtime_ns;
5030} utime_t;
5031
5032/*
Victor Stinner484df002014-10-09 13:52:31 +02005033 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07005034 * they also intentionally leak the declaration of a pointer named "time"
5035 */
5036#define UTIME_TO_TIMESPEC \
5037 struct timespec ts[2]; \
5038 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005039 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005040 time = NULL; \
5041 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005042 ts[0].tv_sec = ut->atime_s; \
5043 ts[0].tv_nsec = ut->atime_ns; \
5044 ts[1].tv_sec = ut->mtime_s; \
5045 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005046 time = ts; \
5047 } \
5048
5049#define UTIME_TO_TIMEVAL \
5050 struct timeval tv[2]; \
5051 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005052 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005053 time = NULL; \
5054 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005055 tv[0].tv_sec = ut->atime_s; \
5056 tv[0].tv_usec = ut->atime_ns / 1000; \
5057 tv[1].tv_sec = ut->mtime_s; \
5058 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005059 time = tv; \
5060 } \
5061
5062#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005063 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005064 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005065 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005066 time = NULL; \
5067 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005068 u.actime = ut->atime_s; \
5069 u.modtime = ut->mtime_s; \
5070 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005071 }
5072
5073#define UTIME_TO_TIME_T \
5074 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005075 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005076 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005077 time = NULL; \
5078 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005079 timet[0] = ut->atime_s; \
5080 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005081 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005082 } \
5083
5084
Victor Stinner528a9ab2015-09-03 21:30:26 +02005085#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005086
5087static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005088utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005089{
Ronald Oussoren41761932020-11-08 10:05:27 +01005090#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5091 if (HAVE_UTIMENSAT_RUNTIME) {
5092 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5093 UTIME_TO_TIMESPEC;
5094 return utimensat(dir_fd, path, time, flags);
5095 } else {
5096 errno = ENOSYS;
5097 return -1;
5098 }
5099#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005100 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5101 UTIME_TO_TIMESPEC;
5102 return utimensat(dir_fd, path, time, flags);
5103#elif defined(HAVE_FUTIMESAT)
5104 UTIME_TO_TIMEVAL;
5105 /*
5106 * follow_symlinks will never be false here;
5107 * we only allow !follow_symlinks and dir_fd together
5108 * if we have utimensat()
5109 */
5110 assert(follow_symlinks);
5111 return futimesat(dir_fd, path, time);
5112#endif
5113}
5114
Larry Hastings2f936352014-08-05 14:04:04 +10005115 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
5116#else
5117 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07005118#endif
5119
Victor Stinner528a9ab2015-09-03 21:30:26 +02005120#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005121
5122static int
Victor Stinner484df002014-10-09 13:52:31 +02005123utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005124{
5125#ifdef HAVE_FUTIMENS
Ronald Oussoren41761932020-11-08 10:05:27 +01005126
5127 if (HAVE_FUTIMENS_RUNTIME) {
5128
Larry Hastings9cf065c2012-06-22 16:30:09 -07005129 UTIME_TO_TIMESPEC;
5130 return futimens(fd, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005131
5132 } else
5133#ifndef HAVE_FUTIMES
5134 {
5135 /* Not sure if this can happen */
5136 PyErr_SetString(
5137 PyExc_RuntimeError,
5138 "neither futimens nor futimes are supported"
5139 " on this system");
5140 return -1;
5141 }
5142#endif
5143
5144#endif
5145#ifdef HAVE_FUTIMES
5146 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005147 UTIME_TO_TIMEVAL;
5148 return futimes(fd, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005149 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005150#endif
5151}
5152
Larry Hastings2f936352014-08-05 14:04:04 +10005153 #define PATH_UTIME_HAVE_FD 1
5154#else
5155 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07005156#endif
5157
Victor Stinner5ebae872015-09-22 01:29:33 +02005158#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
5159# define UTIME_HAVE_NOFOLLOW_SYMLINKS
5160#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005161
Victor Stinner4552ced2015-09-21 22:37:15 +02005162#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005163
5164static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005165utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005166{
5167#ifdef HAVE_UTIMENSAT
Ronald Oussoren41761932020-11-08 10:05:27 +01005168 if (HAVE_UTIMENSAT_RUNTIME) {
5169 UTIME_TO_TIMESPEC;
5170 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
5171 } else
5172#ifndef HAVE_LUTIMES
5173 {
5174 /* Not sure if this can happen */
5175 PyErr_SetString(
5176 PyExc_RuntimeError,
5177 "neither utimensat nor lutimes are supported"
5178 " on this system");
5179 return -1;
5180 }
5181#endif
5182#endif
5183
5184#ifdef HAVE_LUTIMES
5185 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005186 UTIME_TO_TIMEVAL;
5187 return lutimes(path, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005188 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005189#endif
5190}
5191
5192#endif
5193
5194#ifndef MS_WINDOWS
5195
5196static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005197utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005198{
Ronald Oussoren41761932020-11-08 10:05:27 +01005199#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5200 if (HAVE_UTIMENSAT_RUNTIME) {
5201 UTIME_TO_TIMESPEC;
5202 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5203 } else {
5204 UTIME_TO_TIMEVAL;
5205 return utimes(path, time);
5206 }
5207#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005208 UTIME_TO_TIMESPEC;
5209 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5210#elif defined(HAVE_UTIMES)
5211 UTIME_TO_TIMEVAL;
5212 return utimes(path, time);
5213#elif defined(HAVE_UTIME_H)
5214 UTIME_TO_UTIMBUF;
5215 return utime(path, time);
5216#else
5217 UTIME_TO_TIME_T;
5218 return utime(path, time);
5219#endif
5220}
5221
5222#endif
5223
Larry Hastings76ad59b2012-05-03 00:30:07 -07005224static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005225split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
Larry Hastings76ad59b2012-05-03 00:30:07 -07005226{
5227 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04005228 PyObject *divmod;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005229 divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07005230 if (!divmod)
5231 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005232 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
5233 PyErr_Format(PyExc_TypeError,
5234 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08005235 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005236 goto exit;
5237 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005238 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
5239 if ((*s == -1) && PyErr_Occurred())
5240 goto exit;
5241 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04005242 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07005243 goto exit;
5244
5245 result = 1;
5246exit:
5247 Py_XDECREF(divmod);
5248 return result;
5249}
5250
Larry Hastings2f936352014-08-05 14:04:04 +10005251
5252/*[clinic input]
5253os.utime
5254
5255 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005256 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10005257 *
5258 ns: object = NULL
5259 dir_fd: dir_fd(requires='futimensat') = None
5260 follow_symlinks: bool=True
5261
Martin Panter0ff89092015-09-09 01:56:53 +00005262# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10005263
5264Set the access and modified time of path.
5265
5266path may always be specified as a string.
5267On some platforms, path may also be specified as an open file descriptor.
5268 If this functionality is unavailable, using it raises an exception.
5269
5270If times is not None, it must be a tuple (atime, mtime);
5271 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005272If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10005273 atime_ns and mtime_ns should be expressed as integer nanoseconds
5274 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005275If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10005276Specifying tuples for both times and ns is an error.
5277
5278If dir_fd is not None, it should be a file descriptor open to a directory,
5279 and path should be relative; path will then be relative to that directory.
5280If follow_symlinks is False, and the last element of the path is a symbolic
5281 link, utime will modify the symbolic link itself instead of the file the
5282 link points to.
5283It is an error to use dir_fd or follow_symlinks when specifying path
5284 as an open file descriptor.
5285dir_fd and follow_symlinks may not be available on your platform.
5286 If they are unavailable, using them will raise a NotImplementedError.
5287
5288[clinic start generated code]*/
5289
Larry Hastings2f936352014-08-05 14:04:04 +10005290static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005291os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
5292 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005293/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005294{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005295#ifdef MS_WINDOWS
5296 HANDLE hFile;
5297 FILETIME atime, mtime;
5298#else
5299 int result;
5300#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005301
Larry Hastings2f936352014-08-05 14:04:04 +10005302 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005303
Christian Heimesb3c87242013-08-01 00:08:16 +02005304 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07005305
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005306 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005307 PyErr_SetString(PyExc_ValueError,
5308 "utime: you may specify either 'times'"
5309 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005310 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005311 }
5312
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005313 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005314 time_t a_sec, m_sec;
5315 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005316 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005317 PyErr_SetString(PyExc_TypeError,
5318 "utime: 'times' must be either"
5319 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005320 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005321 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005322 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005323 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005324 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005325 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005326 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005327 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005328 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005329 utime.atime_s = a_sec;
5330 utime.atime_ns = a_nsec;
5331 utime.mtime_s = m_sec;
5332 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005333 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005334 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07005335 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005336 PyErr_SetString(PyExc_TypeError,
5337 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005338 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005339 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005340 utime.now = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005341 if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005342 &utime.atime_s, &utime.atime_ns) ||
Victor Stinner1c2fa782020-05-10 11:05:29 +02005343 !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005344 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005345 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005346 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005347 }
5348 else {
5349 /* times and ns are both None/unspecified. use "now". */
5350 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005351 }
5352
Victor Stinner4552ced2015-09-21 22:37:15 +02005353#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005354 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005355 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005356#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005357
Larry Hastings2f936352014-08-05 14:04:04 +10005358 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
5359 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
5360 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005361 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005362
Larry Hastings9cf065c2012-06-22 16:30:09 -07005363#if !defined(HAVE_UTIMENSAT)
5364 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02005365 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005366 "utime: cannot use dir_fd and follow_symlinks "
5367 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005368 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005369 }
5370#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005371
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005372 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
5373 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
5374 return NULL;
5375 }
5376
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005377#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005378 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005379 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5380 NULL, OPEN_EXISTING,
5381 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005382 Py_END_ALLOW_THREADS
5383 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005384 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005385 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005386 }
5387
Larry Hastings9cf065c2012-06-22 16:30:09 -07005388 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005389 GetSystemTimeAsFileTime(&mtime);
5390 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005391 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005392 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005393 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5394 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005395 }
5396 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5397 /* Avoid putting the file name into the error here,
5398 as that may confuse the user into believing that
5399 something is wrong with the file, when it also
5400 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005401 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005402 CloseHandle(hFile);
5403 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005404 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005405 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005406#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005407 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005408
Victor Stinner4552ced2015-09-21 22:37:15 +02005409#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005410 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005411 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005412 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005413#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005414
Victor Stinner528a9ab2015-09-03 21:30:26 +02005415#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Ronald Oussoren41761932020-11-08 10:05:27 +01005416 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
Larry Hastings2f936352014-08-05 14:04:04 +10005417 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Ronald Oussoren41761932020-11-08 10:05:27 +01005418
5419 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07005420#endif
5421
Victor Stinner528a9ab2015-09-03 21:30:26 +02005422#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005423 if (path->fd != -1)
5424 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005425 else
5426#endif
5427
Larry Hastings2f936352014-08-05 14:04:04 +10005428 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005429
5430 Py_END_ALLOW_THREADS
5431
Ronald Oussoren41761932020-11-08 10:05:27 +01005432#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5433 /* See utime_dir_fd implementation */
5434 if (result == -1 && errno == ENOSYS) {
5435 argument_unavailable_error(NULL, "dir_fd");
5436 return NULL;
5437 }
5438#endif
5439
Larry Hastings9cf065c2012-06-22 16:30:09 -07005440 if (result < 0) {
5441 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005442 posix_error();
5443 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005444 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005445
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005446#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005447
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005448 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005449}
5450
Guido van Rossum3b066191991-06-04 19:40:25 +00005451/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005452
Larry Hastings2f936352014-08-05 14:04:04 +10005453
5454/*[clinic input]
5455os._exit
5456
5457 status: int
5458
5459Exit to the system with specified status, without normal exit processing.
5460[clinic start generated code]*/
5461
Larry Hastings2f936352014-08-05 14:04:04 +10005462static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005463os__exit_impl(PyObject *module, int status)
5464/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005465{
5466 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005467 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005468}
5469
Steve Dowercc16be82016-09-08 10:35:16 -07005470#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5471#define EXECV_CHAR wchar_t
5472#else
5473#define EXECV_CHAR char
5474#endif
5475
pxinwrf2d7ac72019-05-21 18:46:37 +08005476#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005477static void
Steve Dowercc16be82016-09-08 10:35:16 -07005478free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005479{
Victor Stinner8c62be82010-05-06 00:08:46 +00005480 Py_ssize_t i;
5481 for (i = 0; i < count; i++)
5482 PyMem_Free(array[i]);
5483 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005484}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005485
Berker Peksag81816462016-09-15 20:19:47 +03005486static int
5487fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005488{
Victor Stinner8c62be82010-05-06 00:08:46 +00005489 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005490 PyObject *ub;
5491 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005492#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005493 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005494 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005495 *out = PyUnicode_AsWideCharString(ub, &size);
5496 if (*out)
5497 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005498#else
Berker Peksag81816462016-09-15 20:19:47 +03005499 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005500 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005501 size = PyBytes_GET_SIZE(ub);
5502 *out = PyMem_Malloc(size + 1);
5503 if (*out) {
5504 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5505 result = 1;
5506 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005507 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005508#endif
Berker Peksag81816462016-09-15 20:19:47 +03005509 Py_DECREF(ub);
5510 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005511}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005512#endif
5513
pxinwrf2d7ac72019-05-21 18:46:37 +08005514#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005515static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005516parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5517{
Victor Stinner8c62be82010-05-06 00:08:46 +00005518 Py_ssize_t i, pos, envc;
5519 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005520 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005521 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005522
Victor Stinner8c62be82010-05-06 00:08:46 +00005523 i = PyMapping_Size(env);
5524 if (i < 0)
5525 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005526 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005527 if (envlist == NULL) {
5528 PyErr_NoMemory();
5529 return NULL;
5530 }
5531 envc = 0;
5532 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005533 if (!keys)
5534 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005535 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005536 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005537 goto error;
5538 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5539 PyErr_Format(PyExc_TypeError,
5540 "env.keys() or env.values() is not a list");
5541 goto error;
5542 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005543
Victor Stinner8c62be82010-05-06 00:08:46 +00005544 for (pos = 0; pos < i; pos++) {
5545 key = PyList_GetItem(keys, pos);
5546 val = PyList_GetItem(vals, pos);
5547 if (!key || !val)
5548 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005549
Berker Peksag81816462016-09-15 20:19:47 +03005550#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5551 if (!PyUnicode_FSDecoder(key, &key2))
5552 goto error;
5553 if (!PyUnicode_FSDecoder(val, &val2)) {
5554 Py_DECREF(key2);
5555 goto error;
5556 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005557 /* Search from index 1 because on Windows starting '=' is allowed for
5558 defining hidden environment variables. */
5559 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5560 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5561 {
5562 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005563 Py_DECREF(key2);
5564 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005565 goto error;
5566 }
Berker Peksag81816462016-09-15 20:19:47 +03005567 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5568#else
5569 if (!PyUnicode_FSConverter(key, &key2))
5570 goto error;
5571 if (!PyUnicode_FSConverter(val, &val2)) {
5572 Py_DECREF(key2);
5573 goto error;
5574 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005575 if (PyBytes_GET_SIZE(key2) == 0 ||
5576 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5577 {
5578 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005579 Py_DECREF(key2);
5580 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005581 goto error;
5582 }
Berker Peksag81816462016-09-15 20:19:47 +03005583 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5584 PyBytes_AS_STRING(val2));
5585#endif
5586 Py_DECREF(key2);
5587 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005588 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005589 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005590
5591 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5592 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005593 goto error;
5594 }
Berker Peksag81816462016-09-15 20:19:47 +03005595
Steve Dowercc16be82016-09-08 10:35:16 -07005596 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005597 }
5598 Py_DECREF(vals);
5599 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005600
Victor Stinner8c62be82010-05-06 00:08:46 +00005601 envlist[envc] = 0;
5602 *envc_ptr = envc;
5603 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005604
5605error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005606 Py_XDECREF(keys);
5607 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005608 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005609 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005610}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005611
Steve Dowercc16be82016-09-08 10:35:16 -07005612static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005613parse_arglist(PyObject* argv, Py_ssize_t *argc)
5614{
5615 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005616 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005617 if (argvlist == NULL) {
5618 PyErr_NoMemory();
5619 return NULL;
5620 }
5621 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005622 PyObject* item = PySequence_ITEM(argv, i);
5623 if (item == NULL)
5624 goto fail;
5625 if (!fsconvert_strdup(item, &argvlist[i])) {
5626 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005627 goto fail;
5628 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005629 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005630 }
5631 argvlist[*argc] = NULL;
5632 return argvlist;
5633fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005634 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005635 free_string_array(argvlist, *argc);
5636 return NULL;
5637}
Steve Dowercc16be82016-09-08 10:35:16 -07005638
Ross Lagerwall7807c352011-03-17 20:20:30 +02005639#endif
5640
Larry Hastings2f936352014-08-05 14:04:04 +10005641
Ross Lagerwall7807c352011-03-17 20:20:30 +02005642#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005643/*[clinic input]
5644os.execv
5645
Steve Dowercc16be82016-09-08 10:35:16 -07005646 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005647 Path of executable file.
5648 argv: object
5649 Tuple or list of strings.
5650 /
5651
5652Execute an executable path with arguments, replacing current process.
5653[clinic start generated code]*/
5654
Larry Hastings2f936352014-08-05 14:04:04 +10005655static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005656os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5657/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005658{
Steve Dowercc16be82016-09-08 10:35:16 -07005659 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005660 Py_ssize_t argc;
5661
5662 /* execv has two arguments: (path, argv), where
5663 argv is a list or tuple of strings. */
5664
Ross Lagerwall7807c352011-03-17 20:20:30 +02005665 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5666 PyErr_SetString(PyExc_TypeError,
5667 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005668 return NULL;
5669 }
5670 argc = PySequence_Size(argv);
5671 if (argc < 1) {
5672 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005673 return NULL;
5674 }
5675
5676 argvlist = parse_arglist(argv, &argc);
5677 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005678 return NULL;
5679 }
Steve Dowerbce26262016-11-19 19:17:26 -08005680 if (!argvlist[0][0]) {
5681 PyErr_SetString(PyExc_ValueError,
5682 "execv() arg 2 first element cannot be empty");
5683 free_string_array(argvlist, argc);
5684 return NULL;
5685 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005686
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005687 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005688 free_string_array(argvlist, argc);
5689 return NULL;
5690 }
5691
Steve Dowerbce26262016-11-19 19:17:26 -08005692 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005693#ifdef HAVE_WEXECV
5694 _wexecv(path->wide, argvlist);
5695#else
5696 execv(path->narrow, argvlist);
5697#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005698 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005699
5700 /* If we get here it's definitely an error */
5701
5702 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005703 return posix_error();
5704}
5705
Larry Hastings2f936352014-08-05 14:04:04 +10005706
5707/*[clinic input]
5708os.execve
5709
5710 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5711 Path of executable file.
5712 argv: object
5713 Tuple or list of strings.
5714 env: object
5715 Dictionary of strings mapping to strings.
5716
5717Execute an executable path with arguments, replacing current process.
5718[clinic start generated code]*/
5719
Larry Hastings2f936352014-08-05 14:04:04 +10005720static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005721os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5722/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005723{
Steve Dowercc16be82016-09-08 10:35:16 -07005724 EXECV_CHAR **argvlist = NULL;
5725 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005726 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005727
Victor Stinner8c62be82010-05-06 00:08:46 +00005728 /* execve has three arguments: (path, argv, env), where
5729 argv is a list or tuple of strings and env is a dictionary
5730 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005731
Ross Lagerwall7807c352011-03-17 20:20:30 +02005732 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005733 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005734 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005735 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005736 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005737 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005738 if (argc < 1) {
5739 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5740 return NULL;
5741 }
5742
Victor Stinner8c62be82010-05-06 00:08:46 +00005743 if (!PyMapping_Check(env)) {
5744 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005745 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005746 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005747 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005748
Ross Lagerwall7807c352011-03-17 20:20:30 +02005749 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005750 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005751 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005752 }
Steve Dowerbce26262016-11-19 19:17:26 -08005753 if (!argvlist[0][0]) {
5754 PyErr_SetString(PyExc_ValueError,
5755 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005756 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005757 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005758
Victor Stinner8c62be82010-05-06 00:08:46 +00005759 envlist = parse_envlist(env, &envc);
5760 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005761 goto fail_0;
5762
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005763 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005764 goto fail_1;
5765 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005766
Steve Dowerbce26262016-11-19 19:17:26 -08005767 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005768#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005769 if (path->fd > -1)
5770 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005771 else
5772#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005773#ifdef HAVE_WEXECV
5774 _wexecve(path->wide, argvlist, envlist);
5775#else
Larry Hastings2f936352014-08-05 14:04:04 +10005776 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005777#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005778 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005779
5780 /* If we get here it's definitely an error */
5781
Alexey Izbyshev83460312018-10-20 03:28:22 +03005782 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005783 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005784 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005785 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005786 if (argvlist)
5787 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005788 return NULL;
5789}
Steve Dowercc16be82016-09-08 10:35:16 -07005790
Larry Hastings9cf065c2012-06-22 16:30:09 -07005791#endif /* HAVE_EXECV */
5792
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005793#ifdef HAVE_POSIX_SPAWN
5794
5795enum posix_spawn_file_actions_identifier {
5796 POSIX_SPAWN_OPEN,
5797 POSIX_SPAWN_CLOSE,
5798 POSIX_SPAWN_DUP2
5799};
5800
William Orr81574b82018-10-01 22:19:56 -07005801#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005802static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005803convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005804#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005805
5806static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005807parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005808 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005809 PyObject *setsigdef, PyObject *scheduler,
5810 posix_spawnattr_t *attrp)
5811{
5812 long all_flags = 0;
5813
5814 errno = posix_spawnattr_init(attrp);
5815 if (errno) {
5816 posix_error();
5817 return -1;
5818 }
5819
5820 if (setpgroup) {
5821 pid_t pgid = PyLong_AsPid(setpgroup);
5822 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5823 goto fail;
5824 }
5825 errno = posix_spawnattr_setpgroup(attrp, pgid);
5826 if (errno) {
5827 posix_error();
5828 goto fail;
5829 }
5830 all_flags |= POSIX_SPAWN_SETPGROUP;
5831 }
5832
5833 if (resetids) {
5834 all_flags |= POSIX_SPAWN_RESETIDS;
5835 }
5836
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005837 if (setsid) {
Ronald Oussoren41761932020-11-08 10:05:27 +01005838#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5839 if (HAVE_POSIX_SPAWN_SETSID_RUNTIME) {
5840#endif
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005841#ifdef POSIX_SPAWN_SETSID
5842 all_flags |= POSIX_SPAWN_SETSID;
5843#elif defined(POSIX_SPAWN_SETSID_NP)
5844 all_flags |= POSIX_SPAWN_SETSID_NP;
5845#else
5846 argument_unavailable_error(func_name, "setsid");
5847 return -1;
5848#endif
Ronald Oussoren41761932020-11-08 10:05:27 +01005849
5850#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5851 } else {
5852 argument_unavailable_error(func_name, "setsid");
5853 return -1;
5854 }
5855#endif /* HAVE_POSIX_SPAWN_SETSID_RUNTIME */
5856
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005857 }
5858
Pablo Galindo254a4662018-09-07 16:44:24 +01005859 if (setsigmask) {
5860 sigset_t set;
5861 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5862 goto fail;
5863 }
5864 errno = posix_spawnattr_setsigmask(attrp, &set);
5865 if (errno) {
5866 posix_error();
5867 goto fail;
5868 }
5869 all_flags |= POSIX_SPAWN_SETSIGMASK;
5870 }
5871
5872 if (setsigdef) {
5873 sigset_t set;
5874 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5875 goto fail;
5876 }
5877 errno = posix_spawnattr_setsigdefault(attrp, &set);
5878 if (errno) {
5879 posix_error();
5880 goto fail;
5881 }
5882 all_flags |= POSIX_SPAWN_SETSIGDEF;
5883 }
5884
5885 if (scheduler) {
5886#ifdef POSIX_SPAWN_SETSCHEDULER
5887 PyObject *py_schedpolicy;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005888 PyObject *schedparam_obj;
Pablo Galindo254a4662018-09-07 16:44:24 +01005889 struct sched_param schedparam;
5890
Victor Stinner1c2fa782020-05-10 11:05:29 +02005891 if (!PyArg_ParseTuple(scheduler, "OO"
Pablo Galindo254a4662018-09-07 16:44:24 +01005892 ";A scheduler tuple must have two elements",
Victor Stinner1c2fa782020-05-10 11:05:29 +02005893 &py_schedpolicy, &schedparam_obj)) {
5894 goto fail;
5895 }
5896 if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005897 goto fail;
5898 }
5899 if (py_schedpolicy != Py_None) {
5900 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5901
5902 if (schedpolicy == -1 && PyErr_Occurred()) {
5903 goto fail;
5904 }
5905 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5906 if (errno) {
5907 posix_error();
5908 goto fail;
5909 }
5910 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5911 }
5912 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5913 if (errno) {
5914 posix_error();
5915 goto fail;
5916 }
5917 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5918#else
5919 PyErr_SetString(PyExc_NotImplementedError,
5920 "The scheduler option is not supported in this system.");
5921 goto fail;
5922#endif
5923 }
5924
5925 errno = posix_spawnattr_setflags(attrp, all_flags);
5926 if (errno) {
5927 posix_error();
5928 goto fail;
5929 }
5930
5931 return 0;
5932
5933fail:
5934 (void)posix_spawnattr_destroy(attrp);
5935 return -1;
5936}
5937
5938static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005939parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005940 posix_spawn_file_actions_t *file_actionsp,
5941 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005942{
5943 PyObject *seq;
5944 PyObject *file_action = NULL;
5945 PyObject *tag_obj;
5946
5947 seq = PySequence_Fast(file_actions,
5948 "file_actions must be a sequence or None");
5949 if (seq == NULL) {
5950 return -1;
5951 }
5952
5953 errno = posix_spawn_file_actions_init(file_actionsp);
5954 if (errno) {
5955 posix_error();
5956 Py_DECREF(seq);
5957 return -1;
5958 }
5959
Zackery Spytzd52a83a2019-06-26 14:54:20 -06005960 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03005961 file_action = PySequence_Fast_GET_ITEM(seq, i);
5962 Py_INCREF(file_action);
5963 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5964 PyErr_SetString(PyExc_TypeError,
5965 "Each file_actions element must be a non-empty tuple");
5966 goto fail;
5967 }
5968 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5969 if (tag == -1 && PyErr_Occurred()) {
5970 goto fail;
5971 }
5972
5973 /* Populate the file_actions object */
5974 switch (tag) {
5975 case POSIX_SPAWN_OPEN: {
5976 int fd, oflag;
5977 PyObject *path;
5978 unsigned long mode;
5979 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5980 ";A open file_action tuple must have 5 elements",
5981 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5982 &oflag, &mode))
5983 {
5984 goto fail;
5985 }
Pablo Galindocb970732018-06-19 09:19:50 +01005986 if (PyList_Append(temp_buffer, path)) {
5987 Py_DECREF(path);
5988 goto fail;
5989 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005990 errno = posix_spawn_file_actions_addopen(file_actionsp,
5991 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005992 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005993 if (errno) {
5994 posix_error();
5995 goto fail;
5996 }
5997 break;
5998 }
5999 case POSIX_SPAWN_CLOSE: {
6000 int fd;
6001 if (!PyArg_ParseTuple(file_action, "Oi"
6002 ";A close file_action tuple must have 2 elements",
6003 &tag_obj, &fd))
6004 {
6005 goto fail;
6006 }
6007 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
6008 if (errno) {
6009 posix_error();
6010 goto fail;
6011 }
6012 break;
6013 }
6014 case POSIX_SPAWN_DUP2: {
6015 int fd1, fd2;
6016 if (!PyArg_ParseTuple(file_action, "Oii"
6017 ";A dup2 file_action tuple must have 3 elements",
6018 &tag_obj, &fd1, &fd2))
6019 {
6020 goto fail;
6021 }
6022 errno = posix_spawn_file_actions_adddup2(file_actionsp,
6023 fd1, fd2);
6024 if (errno) {
6025 posix_error();
6026 goto fail;
6027 }
6028 break;
6029 }
6030 default: {
6031 PyErr_SetString(PyExc_TypeError,
6032 "Unknown file_actions identifier");
6033 goto fail;
6034 }
6035 }
6036 Py_DECREF(file_action);
6037 }
Pablo Galindo254a4662018-09-07 16:44:24 +01006038
Serhiy Storchakaef347532018-05-01 16:45:04 +03006039 Py_DECREF(seq);
6040 return 0;
6041
6042fail:
6043 Py_DECREF(seq);
6044 Py_DECREF(file_action);
6045 (void)posix_spawn_file_actions_destroy(file_actionsp);
6046 return -1;
6047}
6048
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006049
6050static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006051py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
6052 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006053 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006054 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006055{
Victor Stinner325e4ba2019-02-01 15:47:24 +01006056 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006057 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006058 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006059 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006060 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01006061 posix_spawnattr_t attr;
6062 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006063 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006064 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01006065 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006066 pid_t pid;
6067 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006068
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006069 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03006070 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006071 like posix.environ. */
6072
Serhiy Storchakaef347532018-05-01 16:45:04 +03006073 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006074 PyErr_Format(PyExc_TypeError,
6075 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006076 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006077 }
6078 argc = PySequence_Size(argv);
6079 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006080 PyErr_Format(PyExc_ValueError,
6081 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006082 return NULL;
6083 }
6084
6085 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006086 PyErr_Format(PyExc_TypeError,
6087 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006088 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006089 }
6090
6091 argvlist = parse_arglist(argv, &argc);
6092 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006093 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006094 }
6095 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006096 PyErr_Format(PyExc_ValueError,
6097 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006098 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006099 }
6100
6101 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006102 if (envlist == NULL) {
6103 goto exit;
6104 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006105
Anthony Shaw948ed8c2019-05-10 12:00:06 +10006106 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01006107 /* There is a bug in old versions of glibc that makes some of the
6108 * helper functions for manipulating file actions not copy the provided
6109 * buffers. The problem is that posix_spawn_file_actions_addopen does not
6110 * copy the value of path for some old versions of glibc (<2.20).
6111 * The use of temp_buffer here is a workaround that keeps the
6112 * python objects that own the buffers alive until posix_spawn gets called.
6113 * Check https://bugs.python.org/issue33630 and
6114 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
6115 temp_buffer = PyList_New(0);
6116 if (!temp_buffer) {
6117 goto exit;
6118 }
6119 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006120 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006121 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03006122 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006123 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006124
Victor Stinner1c2fa782020-05-10 11:05:29 +02006125 if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
Victor Stinner325e4ba2019-02-01 15:47:24 +01006126 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01006127 goto exit;
6128 }
6129 attrp = &attr;
6130
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006131 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006132 goto exit;
6133 }
6134
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006135 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006136#ifdef HAVE_POSIX_SPAWNP
6137 if (use_posix_spawnp) {
6138 err_code = posix_spawnp(&pid, path->narrow,
6139 file_actionsp, attrp, argvlist, envlist);
6140 }
6141 else
6142#endif /* HAVE_POSIX_SPAWNP */
6143 {
6144 err_code = posix_spawn(&pid, path->narrow,
6145 file_actionsp, attrp, argvlist, envlist);
6146 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006147 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006148
Serhiy Storchakaef347532018-05-01 16:45:04 +03006149 if (err_code) {
6150 errno = err_code;
6151 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006152 goto exit;
6153 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006154#ifdef _Py_MEMORY_SANITIZER
6155 __msan_unpoison(&pid, sizeof(pid));
6156#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006157 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006158
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006159exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03006160 if (file_actionsp) {
6161 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006162 }
Pablo Galindo254a4662018-09-07 16:44:24 +01006163 if (attrp) {
6164 (void)posix_spawnattr_destroy(attrp);
6165 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006166 if (envlist) {
6167 free_string_array(envlist, envc);
6168 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006169 if (argvlist) {
6170 free_string_array(argvlist, argc);
6171 }
Pablo Galindocb970732018-06-19 09:19:50 +01006172 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006173 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006174}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006175
6176
6177/*[clinic input]
6178
6179os.posix_spawn
6180 path: path_t
6181 Path of executable file.
6182 argv: object
6183 Tuple or list of strings.
6184 env: object
6185 Dictionary of strings mapping to strings.
6186 /
6187 *
6188 file_actions: object(c_default='NULL') = ()
6189 A sequence of file action tuples.
6190 setpgroup: object = NULL
6191 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6192 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006193 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
6194 setsid: bool(accept={int}) = False
6195 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006196 setsigmask: object(c_default='NULL') = ()
6197 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6198 setsigdef: object(c_default='NULL') = ()
6199 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6200 scheduler: object = NULL
6201 A tuple with the scheduler policy (optional) and parameters.
6202
6203Execute the program specified by path in a new process.
6204[clinic start generated code]*/
6205
6206static PyObject *
6207os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
6208 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006209 PyObject *setpgroup, int resetids, int setsid,
6210 PyObject *setsigmask, PyObject *setsigdef,
6211 PyObject *scheduler)
6212/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006213{
6214 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006215 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006216 scheduler);
6217}
6218 #endif /* HAVE_POSIX_SPAWN */
6219
6220
6221
6222#ifdef HAVE_POSIX_SPAWNP
6223/*[clinic input]
6224
6225os.posix_spawnp
6226 path: path_t
6227 Path of executable file.
6228 argv: object
6229 Tuple or list of strings.
6230 env: object
6231 Dictionary of strings mapping to strings.
6232 /
6233 *
6234 file_actions: object(c_default='NULL') = ()
6235 A sequence of file action tuples.
6236 setpgroup: object = NULL
6237 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6238 resetids: bool(accept={int}) = False
6239 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006240 setsid: bool(accept={int}) = False
6241 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006242 setsigmask: object(c_default='NULL') = ()
6243 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6244 setsigdef: object(c_default='NULL') = ()
6245 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6246 scheduler: object = NULL
6247 A tuple with the scheduler policy (optional) and parameters.
6248
6249Execute the program specified by path in a new process.
6250[clinic start generated code]*/
6251
6252static PyObject *
6253os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
6254 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006255 PyObject *setpgroup, int resetids, int setsid,
6256 PyObject *setsigmask, PyObject *setsigdef,
6257 PyObject *scheduler)
6258/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006259{
6260 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006261 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006262 scheduler);
6263}
6264#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006265
pxinwrf2d7ac72019-05-21 18:46:37 +08006266#ifdef HAVE_RTPSPAWN
6267static intptr_t
6268_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
6269 const char *envp[])
6270{
6271 RTP_ID rtpid;
6272 int status;
6273 pid_t res;
6274 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006275
pxinwrf2d7ac72019-05-21 18:46:37 +08006276 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
6277 uStackSize=0 cannot be used, the default stack size is too small for
6278 Python. */
6279 if (envp) {
6280 rtpid = rtpSpawn(rtpFileName, argv, envp,
6281 100, 0x1000000, 0, VX_FP_TASK);
6282 }
6283 else {
6284 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
6285 100, 0x1000000, 0, VX_FP_TASK);
6286 }
6287 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
6288 do {
6289 res = waitpid((pid_t)rtpid, &status, 0);
6290 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6291
6292 if (res < 0)
6293 return RTP_ID_ERROR;
6294 return ((intptr_t)status);
6295 }
6296 return ((intptr_t)rtpid);
6297}
6298#endif
6299
6300#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10006301/*[clinic input]
6302os.spawnv
6303
6304 mode: int
6305 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006306 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006307 Path of executable file.
6308 argv: object
6309 Tuple or list of strings.
6310 /
6311
6312Execute the program specified by path in a new process.
6313[clinic start generated code]*/
6314
Larry Hastings2f936352014-08-05 14:04:04 +10006315static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006316os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
6317/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006318{
Steve Dowercc16be82016-09-08 10:35:16 -07006319 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10006320 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00006321 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006322 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006323 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00006324
Victor Stinner8c62be82010-05-06 00:08:46 +00006325 /* spawnv has three arguments: (mode, path, argv), where
6326 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006327
Victor Stinner8c62be82010-05-06 00:08:46 +00006328 if (PyList_Check(argv)) {
6329 argc = PyList_Size(argv);
6330 getitem = PyList_GetItem;
6331 }
6332 else if (PyTuple_Check(argv)) {
6333 argc = PyTuple_Size(argv);
6334 getitem = PyTuple_GetItem;
6335 }
6336 else {
6337 PyErr_SetString(PyExc_TypeError,
6338 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00006339 return NULL;
6340 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006341 if (argc == 0) {
6342 PyErr_SetString(PyExc_ValueError,
6343 "spawnv() arg 2 cannot be empty");
6344 return NULL;
6345 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006346
Steve Dowercc16be82016-09-08 10:35:16 -07006347 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006348 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006349 return PyErr_NoMemory();
6350 }
6351 for (i = 0; i < argc; i++) {
6352 if (!fsconvert_strdup((*getitem)(argv, i),
6353 &argvlist[i])) {
6354 free_string_array(argvlist, i);
6355 PyErr_SetString(
6356 PyExc_TypeError,
6357 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 return NULL;
6359 }
Steve Dower93ff8722016-11-19 19:03:54 -08006360 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02006361 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08006362 PyErr_SetString(
6363 PyExc_ValueError,
6364 "spawnv() arg 2 first element cannot be empty");
6365 return NULL;
6366 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 }
6368 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006369
pxinwrf2d7ac72019-05-21 18:46:37 +08006370#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 if (mode == _OLD_P_OVERLAY)
6372 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006373#endif
Tim Peters5aa91602002-01-30 05:46:57 +00006374
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006375 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08006376 Py_None) < 0) {
6377 free_string_array(argvlist, argc);
6378 return NULL;
6379 }
6380
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006382 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006383#ifdef HAVE_WSPAWNV
6384 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006385#elif defined(HAVE_RTPSPAWN)
6386 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07006387#else
6388 spawnval = _spawnv(mode, path->narrow, argvlist);
6389#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006390 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006391 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00006392
Victor Stinner8c62be82010-05-06 00:08:46 +00006393 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00006394
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 if (spawnval == -1)
6396 return posix_error();
6397 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006398 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006399}
6400
Larry Hastings2f936352014-08-05 14:04:04 +10006401/*[clinic input]
6402os.spawnve
6403
6404 mode: int
6405 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006406 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006407 Path of executable file.
6408 argv: object
6409 Tuple or list of strings.
6410 env: object
6411 Dictionary of strings mapping to strings.
6412 /
6413
6414Execute the program specified by path in a new process.
6415[clinic start generated code]*/
6416
Larry Hastings2f936352014-08-05 14:04:04 +10006417static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006418os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006419 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006420/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006421{
Steve Dowercc16be82016-09-08 10:35:16 -07006422 EXECV_CHAR **argvlist;
6423 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006424 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006425 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006426 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006427 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006428 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006429
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 /* spawnve has four arguments: (mode, path, argv, env), where
6431 argv is a list or tuple of strings and env is a dictionary
6432 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006433
Victor Stinner8c62be82010-05-06 00:08:46 +00006434 if (PyList_Check(argv)) {
6435 argc = PyList_Size(argv);
6436 getitem = PyList_GetItem;
6437 }
6438 else if (PyTuple_Check(argv)) {
6439 argc = PyTuple_Size(argv);
6440 getitem = PyTuple_GetItem;
6441 }
6442 else {
6443 PyErr_SetString(PyExc_TypeError,
6444 "spawnve() arg 2 must be a tuple or list");
6445 goto fail_0;
6446 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006447 if (argc == 0) {
6448 PyErr_SetString(PyExc_ValueError,
6449 "spawnve() arg 2 cannot be empty");
6450 goto fail_0;
6451 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 if (!PyMapping_Check(env)) {
6453 PyErr_SetString(PyExc_TypeError,
6454 "spawnve() arg 3 must be a mapping object");
6455 goto fail_0;
6456 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006457
Steve Dowercc16be82016-09-08 10:35:16 -07006458 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006459 if (argvlist == NULL) {
6460 PyErr_NoMemory();
6461 goto fail_0;
6462 }
6463 for (i = 0; i < argc; i++) {
6464 if (!fsconvert_strdup((*getitem)(argv, i),
6465 &argvlist[i]))
6466 {
6467 lastarg = i;
6468 goto fail_1;
6469 }
Steve Dowerbce26262016-11-19 19:17:26 -08006470 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006471 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006472 PyErr_SetString(
6473 PyExc_ValueError,
6474 "spawnv() arg 2 first element cannot be empty");
6475 goto fail_1;
6476 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 }
6478 lastarg = argc;
6479 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006480
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 envlist = parse_envlist(env, &envc);
6482 if (envlist == NULL)
6483 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006484
pxinwrf2d7ac72019-05-21 18:46:37 +08006485#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006486 if (mode == _OLD_P_OVERLAY)
6487 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006488#endif
Tim Peters25059d32001-12-07 20:35:43 +00006489
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006490 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006491 goto fail_2;
6492 }
6493
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006495 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006496#ifdef HAVE_WSPAWNV
6497 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006498#elif defined(HAVE_RTPSPAWN)
6499 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6500 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006501#else
6502 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6503#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006504 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006506
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 if (spawnval == -1)
6508 (void) posix_error();
6509 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006510 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006511
Saiyang Gou95f60012020-02-04 16:15:00 -08006512 fail_2:
Victor Stinner8c62be82010-05-06 00:08:46 +00006513 while (--envc >= 0)
6514 PyMem_DEL(envlist[envc]);
6515 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006516 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006517 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006518 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006519 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006520}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006521
Guido van Rossuma1065681999-01-25 23:20:23 +00006522#endif /* HAVE_SPAWNV */
6523
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006524#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006525
6526/* Helper function to validate arguments.
6527 Returns 0 on success. non-zero on failure with a TypeError raised.
6528 If obj is non-NULL it must be callable. */
6529static int
6530check_null_or_callable(PyObject *obj, const char* obj_name)
6531{
6532 if (obj && !PyCallable_Check(obj)) {
6533 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006534 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006535 return -1;
6536 }
6537 return 0;
6538}
6539
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006540/*[clinic input]
6541os.register_at_fork
6542
Gregory P. Smith163468a2017-05-29 10:03:41 -07006543 *
6544 before: object=NULL
6545 A callable to be called in the parent before the fork() syscall.
6546 after_in_child: object=NULL
6547 A callable to be called in the child after fork().
6548 after_in_parent: object=NULL
6549 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006550
Gregory P. Smith163468a2017-05-29 10:03:41 -07006551Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006552
Gregory P. Smith163468a2017-05-29 10:03:41 -07006553'before' callbacks are called in reverse order.
6554'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006555
6556[clinic start generated code]*/
6557
6558static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006559os_register_at_fork_impl(PyObject *module, PyObject *before,
6560 PyObject *after_in_child, PyObject *after_in_parent)
6561/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006562{
6563 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006564
Gregory P. Smith163468a2017-05-29 10:03:41 -07006565 if (!before && !after_in_child && !after_in_parent) {
6566 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6567 return NULL;
6568 }
6569 if (check_null_or_callable(before, "before") ||
6570 check_null_or_callable(after_in_child, "after_in_child") ||
6571 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006572 return NULL;
6573 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006574 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006575
Gregory P. Smith163468a2017-05-29 10:03:41 -07006576 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006577 return NULL;
6578 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006579 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006580 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006581 }
6582 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6583 return NULL;
6584 }
6585 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006586}
6587#endif /* HAVE_FORK */
6588
6589
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006590#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006591/*[clinic input]
6592os.fork1
6593
6594Fork a child process with a single multiplexed (i.e., not bound) thread.
6595
6596Return 0 to child process and PID of child to parent process.
6597[clinic start generated code]*/
6598
Larry Hastings2f936352014-08-05 14:04:04 +10006599static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006600os_fork1_impl(PyObject *module)
6601/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006602{
Victor Stinner8c62be82010-05-06 00:08:46 +00006603 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006604
Victor Stinner81a7be32020-04-14 15:14:01 +02006605 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006606 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6607 return NULL;
6608 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006609 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 pid = fork1();
6611 if (pid == 0) {
6612 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006613 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 } else {
6615 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006616 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 }
6618 if (pid == -1)
6619 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006621}
Larry Hastings2f936352014-08-05 14:04:04 +10006622#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006623
6624
Guido van Rossumad0ee831995-03-01 10:34:45 +00006625#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006626/*[clinic input]
6627os.fork
6628
6629Fork a child process.
6630
6631Return 0 to child process and PID of child to parent process.
6632[clinic start generated code]*/
6633
Larry Hastings2f936352014-08-05 14:04:04 +10006634static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006635os_fork_impl(PyObject *module)
6636/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006637{
Victor Stinner8c62be82010-05-06 00:08:46 +00006638 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006639 PyInterpreterState *interp = _PyInterpreterState_GET();
6640 if (interp->config._isolated_interpreter) {
6641 PyErr_SetString(PyExc_RuntimeError,
6642 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006643 return NULL;
6644 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006645 if (PySys_Audit("os.fork", NULL) < 0) {
6646 return NULL;
6647 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006648 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 pid = fork();
6650 if (pid == 0) {
6651 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006652 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006653 } else {
6654 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006655 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006656 }
6657 if (pid == -1)
6658 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006660}
Larry Hastings2f936352014-08-05 14:04:04 +10006661#endif /* HAVE_FORK */
6662
Guido van Rossum85e3b011991-06-03 12:42:10 +00006663
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006664#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006665#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006666/*[clinic input]
6667os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006668
Larry Hastings2f936352014-08-05 14:04:04 +10006669 policy: int
6670
6671Get the maximum scheduling priority for policy.
6672[clinic start generated code]*/
6673
Larry Hastings2f936352014-08-05 14:04:04 +10006674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006675os_sched_get_priority_max_impl(PyObject *module, int policy)
6676/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006677{
6678 int max;
6679
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006680 max = sched_get_priority_max(policy);
6681 if (max < 0)
6682 return posix_error();
6683 return PyLong_FromLong(max);
6684}
6685
Larry Hastings2f936352014-08-05 14:04:04 +10006686
6687/*[clinic input]
6688os.sched_get_priority_min
6689
6690 policy: int
6691
6692Get the minimum scheduling priority for policy.
6693[clinic start generated code]*/
6694
Larry Hastings2f936352014-08-05 14:04:04 +10006695static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006696os_sched_get_priority_min_impl(PyObject *module, int policy)
6697/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006698{
6699 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006700 if (min < 0)
6701 return posix_error();
6702 return PyLong_FromLong(min);
6703}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006704#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6705
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006706
Larry Hastings2f936352014-08-05 14:04:04 +10006707#ifdef HAVE_SCHED_SETSCHEDULER
6708/*[clinic input]
6709os.sched_getscheduler
6710 pid: pid_t
6711 /
6712
Min ho Kimc4cacc82019-07-31 08:16:13 +10006713Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006714
6715Passing 0 for pid returns the scheduling policy for the calling process.
6716[clinic start generated code]*/
6717
Larry Hastings2f936352014-08-05 14:04:04 +10006718static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006719os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006720/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006721{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006722 int policy;
6723
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006724 policy = sched_getscheduler(pid);
6725 if (policy < 0)
6726 return posix_error();
6727 return PyLong_FromLong(policy);
6728}
Larry Hastings2f936352014-08-05 14:04:04 +10006729#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006730
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006731
William Orr81574b82018-10-01 22:19:56 -07006732#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006733/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006734class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006735
6736@classmethod
6737os.sched_param.__new__
6738
6739 sched_priority: object
6740 A scheduling parameter.
6741
Eddie Elizondob3966632019-11-05 07:16:14 -08006742Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006743[clinic start generated code]*/
6744
Larry Hastings2f936352014-08-05 14:04:04 +10006745static PyObject *
6746os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006747/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006748{
6749 PyObject *res;
6750
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006751 res = PyStructSequence_New(type);
6752 if (!res)
6753 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006754 Py_INCREF(sched_priority);
6755 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006756 return res;
6757}
6758
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006759PyDoc_VAR(os_sched_param__doc__);
6760
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006761static PyStructSequence_Field sched_param_fields[] = {
6762 {"sched_priority", "the scheduling priority"},
6763 {0}
6764};
6765
6766static PyStructSequence_Desc sched_param_desc = {
6767 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006768 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006769 sched_param_fields,
6770 1
6771};
6772
6773static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006774convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006775{
6776 long priority;
6777
Victor Stinner1c2fa782020-05-10 11:05:29 +02006778 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006779 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6780 return 0;
6781 }
6782 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6783 if (priority == -1 && PyErr_Occurred())
6784 return 0;
6785 if (priority > INT_MAX || priority < INT_MIN) {
6786 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6787 return 0;
6788 }
6789 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6790 return 1;
6791}
William Orr81574b82018-10-01 22:19:56 -07006792#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006793
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006794
6795#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006796/*[clinic input]
6797os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006798
Larry Hastings2f936352014-08-05 14:04:04 +10006799 pid: pid_t
6800 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006801 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006802 /
6803
6804Set the scheduling policy for the process identified by pid.
6805
6806If pid is 0, the calling process is changed.
6807param is an instance of sched_param.
6808[clinic start generated code]*/
6809
Larry Hastings2f936352014-08-05 14:04:04 +10006810static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006811os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006812 PyObject *param_obj)
6813/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006814{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006815 struct sched_param param;
6816 if (!convert_sched_param(module, param_obj, &param)) {
6817 return NULL;
6818 }
6819
Jesus Cea9c822272011-09-10 01:40:52 +02006820 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006821 ** sched_setscheduler() returns 0 in Linux, but the previous
6822 ** scheduling policy under Solaris/Illumos, and others.
6823 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006824 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006825 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006826 return posix_error();
6827 Py_RETURN_NONE;
6828}
Larry Hastings2f936352014-08-05 14:04:04 +10006829#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006830
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006831
6832#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006833/*[clinic input]
6834os.sched_getparam
6835 pid: pid_t
6836 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006837
Larry Hastings2f936352014-08-05 14:04:04 +10006838Returns scheduling parameters for the process identified by pid.
6839
6840If pid is 0, returns parameters for the calling process.
6841Return value is an instance of sched_param.
6842[clinic start generated code]*/
6843
Larry Hastings2f936352014-08-05 14:04:04 +10006844static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006845os_sched_getparam_impl(PyObject *module, pid_t pid)
6846/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006847{
6848 struct sched_param param;
6849 PyObject *result;
6850 PyObject *priority;
6851
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006852 if (sched_getparam(pid, &param))
6853 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006854 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006855 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006856 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006857 return NULL;
6858 priority = PyLong_FromLong(param.sched_priority);
6859 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006860 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006861 return NULL;
6862 }
Larry Hastings2f936352014-08-05 14:04:04 +10006863 PyStructSequence_SET_ITEM(result, 0, priority);
6864 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006865}
6866
Larry Hastings2f936352014-08-05 14:04:04 +10006867
6868/*[clinic input]
6869os.sched_setparam
6870 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006871 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006872 /
6873
6874Set scheduling parameters for the process identified by pid.
6875
6876If pid is 0, sets parameters for the calling process.
6877param should be an instance of sched_param.
6878[clinic start generated code]*/
6879
Larry Hastings2f936352014-08-05 14:04:04 +10006880static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006881os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6882/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006883{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006884 struct sched_param param;
6885 if (!convert_sched_param(module, param_obj, &param)) {
6886 return NULL;
6887 }
6888
6889 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006890 return posix_error();
6891 Py_RETURN_NONE;
6892}
Larry Hastings2f936352014-08-05 14:04:04 +10006893#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006894
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006895
6896#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006897/*[clinic input]
6898os.sched_rr_get_interval -> double
6899 pid: pid_t
6900 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006901
Larry Hastings2f936352014-08-05 14:04:04 +10006902Return the round-robin quantum for the process identified by pid, in seconds.
6903
6904Value returned is a float.
6905[clinic start generated code]*/
6906
Larry Hastings2f936352014-08-05 14:04:04 +10006907static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006908os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6909/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006910{
6911 struct timespec interval;
6912 if (sched_rr_get_interval(pid, &interval)) {
6913 posix_error();
6914 return -1.0;
6915 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006916#ifdef _Py_MEMORY_SANITIZER
6917 __msan_unpoison(&interval, sizeof(interval));
6918#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006919 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6920}
6921#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006922
Larry Hastings2f936352014-08-05 14:04:04 +10006923
6924/*[clinic input]
6925os.sched_yield
6926
6927Voluntarily relinquish the CPU.
6928[clinic start generated code]*/
6929
Larry Hastings2f936352014-08-05 14:04:04 +10006930static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006931os_sched_yield_impl(PyObject *module)
6932/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006933{
6934 if (sched_yield())
6935 return posix_error();
6936 Py_RETURN_NONE;
6937}
6938
Benjamin Peterson2740af82011-08-02 17:41:34 -05006939#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006940/* The minimum number of CPUs allocated in a cpu_set_t */
6941static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006942
Larry Hastings2f936352014-08-05 14:04:04 +10006943/*[clinic input]
6944os.sched_setaffinity
6945 pid: pid_t
6946 mask : object
6947 /
6948
6949Set the CPU affinity of the process identified by pid to mask.
6950
6951mask should be an iterable of integers identifying CPUs.
6952[clinic start generated code]*/
6953
Larry Hastings2f936352014-08-05 14:04:04 +10006954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006955os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6956/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006957{
Antoine Pitrou84869872012-08-04 16:16:35 +02006958 int ncpus;
6959 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006960 cpu_set_t *cpu_set = NULL;
6961 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006962
Larry Hastings2f936352014-08-05 14:04:04 +10006963 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006964 if (iterator == NULL)
6965 return NULL;
6966
6967 ncpus = NCPUS_START;
6968 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006969 cpu_set = CPU_ALLOC(ncpus);
6970 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006971 PyErr_NoMemory();
6972 goto error;
6973 }
Larry Hastings2f936352014-08-05 14:04:04 +10006974 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006975
6976 while ((item = PyIter_Next(iterator))) {
6977 long cpu;
6978 if (!PyLong_Check(item)) {
6979 PyErr_Format(PyExc_TypeError,
6980 "expected an iterator of ints, "
6981 "but iterator yielded %R",
6982 Py_TYPE(item));
6983 Py_DECREF(item);
6984 goto error;
6985 }
6986 cpu = PyLong_AsLong(item);
6987 Py_DECREF(item);
6988 if (cpu < 0) {
6989 if (!PyErr_Occurred())
6990 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6991 goto error;
6992 }
6993 if (cpu > INT_MAX - 1) {
6994 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6995 goto error;
6996 }
6997 if (cpu >= ncpus) {
6998 /* Grow CPU mask to fit the CPU number */
6999 int newncpus = ncpus;
7000 cpu_set_t *newmask;
7001 size_t newsetsize;
7002 while (newncpus <= cpu) {
7003 if (newncpus > INT_MAX / 2)
7004 newncpus = cpu + 1;
7005 else
7006 newncpus = newncpus * 2;
7007 }
7008 newmask = CPU_ALLOC(newncpus);
7009 if (newmask == NULL) {
7010 PyErr_NoMemory();
7011 goto error;
7012 }
7013 newsetsize = CPU_ALLOC_SIZE(newncpus);
7014 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10007015 memcpy(newmask, cpu_set, setsize);
7016 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007017 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007018 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02007019 ncpus = newncpus;
7020 }
Larry Hastings2f936352014-08-05 14:04:04 +10007021 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007022 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07007023 if (PyErr_Occurred()) {
7024 goto error;
7025 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007026 Py_CLEAR(iterator);
7027
Larry Hastings2f936352014-08-05 14:04:04 +10007028 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007029 posix_error();
7030 goto error;
7031 }
Larry Hastings2f936352014-08-05 14:04:04 +10007032 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007033 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02007034
7035error:
Larry Hastings2f936352014-08-05 14:04:04 +10007036 if (cpu_set)
7037 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007038 Py_XDECREF(iterator);
7039 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007040}
7041
Larry Hastings2f936352014-08-05 14:04:04 +10007042
7043/*[clinic input]
7044os.sched_getaffinity
7045 pid: pid_t
7046 /
7047
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01007048Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10007049
7050The affinity is returned as a set of CPU identifiers.
7051[clinic start generated code]*/
7052
Larry Hastings2f936352014-08-05 14:04:04 +10007053static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007054os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03007055/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007056{
Antoine Pitrou84869872012-08-04 16:16:35 +02007057 int cpu, ncpus, count;
7058 size_t setsize;
7059 cpu_set_t *mask = NULL;
7060 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007061
Antoine Pitrou84869872012-08-04 16:16:35 +02007062 ncpus = NCPUS_START;
7063 while (1) {
7064 setsize = CPU_ALLOC_SIZE(ncpus);
7065 mask = CPU_ALLOC(ncpus);
7066 if (mask == NULL)
7067 return PyErr_NoMemory();
7068 if (sched_getaffinity(pid, setsize, mask) == 0)
7069 break;
7070 CPU_FREE(mask);
7071 if (errno != EINVAL)
7072 return posix_error();
7073 if (ncpus > INT_MAX / 2) {
7074 PyErr_SetString(PyExc_OverflowError, "could not allocate "
7075 "a large enough CPU set");
7076 return NULL;
7077 }
7078 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007079 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007080
7081 res = PySet_New(NULL);
7082 if (res == NULL)
7083 goto error;
7084 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
7085 if (CPU_ISSET_S(cpu, setsize, mask)) {
7086 PyObject *cpu_num = PyLong_FromLong(cpu);
7087 --count;
7088 if (cpu_num == NULL)
7089 goto error;
7090 if (PySet_Add(res, cpu_num)) {
7091 Py_DECREF(cpu_num);
7092 goto error;
7093 }
7094 Py_DECREF(cpu_num);
7095 }
7096 }
7097 CPU_FREE(mask);
7098 return res;
7099
7100error:
7101 if (mask)
7102 CPU_FREE(mask);
7103 Py_XDECREF(res);
7104 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007105}
7106
Benjamin Peterson2740af82011-08-02 17:41:34 -05007107#endif /* HAVE_SCHED_SETAFFINITY */
7108
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007109#endif /* HAVE_SCHED_H */
7110
Larry Hastings2f936352014-08-05 14:04:04 +10007111
Neal Norwitzb59798b2003-03-21 01:43:31 +00007112/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00007113#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Victor Stinner57766632020-10-29 15:16:23 +01007114# define DEV_PTY_FILE "/dev/ptc"
7115# define HAVE_DEV_PTMX
Neal Norwitzb59798b2003-03-21 01:43:31 +00007116#else
Victor Stinner57766632020-10-29 15:16:23 +01007117# define DEV_PTY_FILE "/dev/ptmx"
Neal Norwitzb59798b2003-03-21 01:43:31 +00007118#endif
7119
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007120#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00007121#ifdef HAVE_PTY_H
7122#include <pty.h>
7123#else
7124#ifdef HAVE_LIBUTIL_H
7125#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00007126#else
7127#ifdef HAVE_UTIL_H
7128#include <util.h>
7129#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007130#endif /* HAVE_LIBUTIL_H */
7131#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00007132#ifdef HAVE_STROPTS_H
7133#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007134#endif
ngie-eign7745ec42018-02-14 11:54:28 -08007135#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007136
Larry Hastings2f936352014-08-05 14:04:04 +10007137
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007138#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10007139/*[clinic input]
7140os.openpty
7141
7142Open a pseudo-terminal.
7143
7144Return a tuple of (master_fd, slave_fd) containing open file descriptors
7145for both the master and slave ends.
7146[clinic start generated code]*/
7147
Larry Hastings2f936352014-08-05 14:04:04 +10007148static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007149os_openpty_impl(PyObject *module)
7150/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007151{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007152 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007153#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007154 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007155#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007156#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007157 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01007158#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007160#endif
7161#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00007162
Thomas Wouters70c21a12000-07-14 14:28:33 +00007163#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007164 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007165 goto posix_error;
7166
7167 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7168 goto error;
7169 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
7170 goto error;
7171
Neal Norwitzb59798b2003-03-21 01:43:31 +00007172#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007173 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
7174 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007175 goto posix_error;
7176 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7177 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007178
Victor Stinnerdaf45552013-08-28 00:53:59 +02007179 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01007181 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007182
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007183#else
Victor Stinner000de532013-11-25 23:19:58 +01007184 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00007185 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007186 goto posix_error;
7187
Victor Stinner8c62be82010-05-06 00:08:46 +00007188 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007189
Victor Stinner8c62be82010-05-06 00:08:46 +00007190 /* change permission of slave */
7191 if (grantpt(master_fd) < 0) {
7192 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007193 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007194 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007195
Victor Stinner8c62be82010-05-06 00:08:46 +00007196 /* unlock slave */
7197 if (unlockpt(master_fd) < 0) {
7198 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007199 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007200 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007201
Victor Stinner8c62be82010-05-06 00:08:46 +00007202 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007203
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 slave_name = ptsname(master_fd); /* get name of slave */
7205 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007206 goto posix_error;
7207
7208 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01007209 if (slave_fd == -1)
7210 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01007211
7212 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7213 goto posix_error;
7214
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02007215#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00007216 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
7217 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00007218#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00007219 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00007220#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007221#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00007222#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00007223
Victor Stinner8c62be82010-05-06 00:08:46 +00007224 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00007225
Victor Stinnerdaf45552013-08-28 00:53:59 +02007226posix_error:
7227 posix_error();
7228error:
7229 if (master_fd != -1)
7230 close(master_fd);
7231 if (slave_fd != -1)
7232 close(slave_fd);
7233 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00007234}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007235#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007236
Larry Hastings2f936352014-08-05 14:04:04 +10007237
Fred Drake8cef4cf2000-06-28 16:40:38 +00007238#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10007239/*[clinic input]
7240os.forkpty
7241
7242Fork a new process with a new pseudo-terminal as controlling tty.
7243
7244Returns a tuple of (pid, master_fd).
7245Like fork(), return pid of 0 to the child process,
7246and pid of child to the parent process.
7247To both, return fd of newly opened pseudo-terminal.
7248[clinic start generated code]*/
7249
Larry Hastings2f936352014-08-05 14:04:04 +10007250static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007251os_forkpty_impl(PyObject *module)
7252/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007253{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007254 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00007255 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00007256
Victor Stinner81a7be32020-04-14 15:14:01 +02007257 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07007258 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
7259 return NULL;
7260 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007261 if (PySys_Audit("os.forkpty", NULL) < 0) {
7262 return NULL;
7263 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007264 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00007265 pid = forkpty(&master_fd, NULL, NULL, NULL);
7266 if (pid == 0) {
7267 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007268 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00007269 } else {
7270 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007271 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00007272 }
7273 if (pid == -1)
7274 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007275 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00007276}
Larry Hastings2f936352014-08-05 14:04:04 +10007277#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007278
Ross Lagerwall7807c352011-03-17 20:20:30 +02007279
Guido van Rossumad0ee831995-03-01 10:34:45 +00007280#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007281/*[clinic input]
7282os.getegid
7283
7284Return the current process's effective group id.
7285[clinic start generated code]*/
7286
Larry Hastings2f936352014-08-05 14:04:04 +10007287static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007288os_getegid_impl(PyObject *module)
7289/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007290{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007291 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007292}
Larry Hastings2f936352014-08-05 14:04:04 +10007293#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007294
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007295
Guido van Rossumad0ee831995-03-01 10:34:45 +00007296#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007297/*[clinic input]
7298os.geteuid
7299
7300Return the current process's effective user id.
7301[clinic start generated code]*/
7302
Larry Hastings2f936352014-08-05 14:04:04 +10007303static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007304os_geteuid_impl(PyObject *module)
7305/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007306{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007307 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007308}
Larry Hastings2f936352014-08-05 14:04:04 +10007309#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007311
Guido van Rossumad0ee831995-03-01 10:34:45 +00007312#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007313/*[clinic input]
7314os.getgid
7315
7316Return the current process's group id.
7317[clinic start generated code]*/
7318
Larry Hastings2f936352014-08-05 14:04:04 +10007319static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007320os_getgid_impl(PyObject *module)
7321/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007322{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007323 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007324}
Larry Hastings2f936352014-08-05 14:04:04 +10007325#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007327
Berker Peksag39404992016-09-15 20:45:16 +03007328#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10007329/*[clinic input]
7330os.getpid
7331
7332Return the current process id.
7333[clinic start generated code]*/
7334
Larry Hastings2f936352014-08-05 14:04:04 +10007335static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007336os_getpid_impl(PyObject *module)
7337/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007338{
Victor Stinner8c62be82010-05-06 00:08:46 +00007339 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00007340}
Berker Peksag39404992016-09-15 20:45:16 +03007341#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007342
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007343#ifdef NGROUPS_MAX
7344#define MAX_GROUPS NGROUPS_MAX
7345#else
7346 /* defined to be 16 on Solaris7, so this should be a small number */
7347#define MAX_GROUPS 64
7348#endif
7349
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007350#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10007351
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007352#ifdef __APPLE__
7353/*[clinic input]
7354os.getgrouplist
7355
7356 user: str
7357 username to lookup
7358 group as basegid: int
7359 base group id of the user
7360 /
7361
7362Returns a list of groups to which a user belongs.
7363[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007364
7365static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007366os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
7367/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
7368#else
7369/*[clinic input]
7370os.getgrouplist
7371
7372 user: str
7373 username to lookup
7374 group as basegid: gid_t
7375 base group id of the user
7376 /
7377
7378Returns a list of groups to which a user belongs.
7379[clinic start generated code]*/
7380
7381static PyObject *
7382os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
7383/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
7384#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007385{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007386 int i, ngroups;
7387 PyObject *list;
7388#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007389 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007390#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007391 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007392#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007393
7394 /*
7395 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7396 * number of supplimental groups a users can belong to.
7397 * We have to increment it by one because
7398 * getgrouplist() returns both the supplemental groups
7399 * and the primary group, i.e. all of the groups the
7400 * user belongs to.
7401 */
7402 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007403
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007404 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007405#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007406 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007407#else
7408 groups = PyMem_New(gid_t, ngroups);
7409#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007410 if (groups == NULL) {
7411 return PyErr_NoMemory();
7412 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007413
7414 int old_ngroups = ngroups;
7415 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7416 /* Success */
7417 break;
7418 }
7419
7420 /* getgrouplist() fails if the group list is too small */
7421 PyMem_Free(groups);
7422
7423 if (ngroups > old_ngroups) {
7424 /* If the group list is too small, the glibc implementation of
7425 getgrouplist() sets ngroups to the total number of groups and
7426 returns -1. */
7427 }
7428 else {
7429 /* Double the group list size */
7430 if (ngroups > INT_MAX / 2) {
7431 return PyErr_NoMemory();
7432 }
7433 ngroups *= 2;
7434 }
7435
7436 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007437 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007438
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007439#ifdef _Py_MEMORY_SANITIZER
7440 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7441 __msan_unpoison(&ngroups, sizeof(ngroups));
7442 __msan_unpoison(groups, ngroups*sizeof(*groups));
7443#endif
7444
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007445 list = PyList_New(ngroups);
7446 if (list == NULL) {
7447 PyMem_Del(groups);
7448 return NULL;
7449 }
7450
7451 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007452#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007453 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007454#else
7455 PyObject *o = _PyLong_FromGid(groups[i]);
7456#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007457 if (o == NULL) {
7458 Py_DECREF(list);
7459 PyMem_Del(groups);
7460 return NULL;
7461 }
7462 PyList_SET_ITEM(list, i, o);
7463 }
7464
7465 PyMem_Del(groups);
7466
7467 return list;
7468}
Larry Hastings2f936352014-08-05 14:04:04 +10007469#endif /* HAVE_GETGROUPLIST */
7470
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007471
Fred Drakec9680921999-12-13 16:37:25 +00007472#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007473/*[clinic input]
7474os.getgroups
7475
7476Return list of supplemental group IDs for the process.
7477[clinic start generated code]*/
7478
Larry Hastings2f936352014-08-05 14:04:04 +10007479static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007480os_getgroups_impl(PyObject *module)
7481/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007482{
7483 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007484 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007485
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007486 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007487 * This is a helper variable to store the intermediate result when
7488 * that happens.
7489 *
7490 * To keep the code readable the OSX behaviour is unconditional,
7491 * according to the POSIX spec this should be safe on all unix-y
7492 * systems.
7493 */
7494 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007495 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007496
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007497#ifdef __APPLE__
7498 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7499 * there are more groups than can fit in grouplist. Therefore, on OS X
7500 * always first call getgroups with length 0 to get the actual number
7501 * of groups.
7502 */
7503 n = getgroups(0, NULL);
7504 if (n < 0) {
7505 return posix_error();
7506 } else if (n <= MAX_GROUPS) {
7507 /* groups will fit in existing array */
7508 alt_grouplist = grouplist;
7509 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007510 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007511 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007512 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007513 }
7514 }
7515
7516 n = getgroups(n, alt_grouplist);
7517 if (n == -1) {
7518 if (alt_grouplist != grouplist) {
7519 PyMem_Free(alt_grouplist);
7520 }
7521 return posix_error();
7522 }
7523#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007524 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007525 if (n < 0) {
7526 if (errno == EINVAL) {
7527 n = getgroups(0, NULL);
7528 if (n == -1) {
7529 return posix_error();
7530 }
7531 if (n == 0) {
7532 /* Avoid malloc(0) */
7533 alt_grouplist = grouplist;
7534 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007535 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007536 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007537 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007538 }
7539 n = getgroups(n, alt_grouplist);
7540 if (n == -1) {
7541 PyMem_Free(alt_grouplist);
7542 return posix_error();
7543 }
7544 }
7545 } else {
7546 return posix_error();
7547 }
7548 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007549#endif
7550
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007551 result = PyList_New(n);
7552 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007553 int i;
7554 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007555 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007556 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007557 Py_DECREF(result);
7558 result = NULL;
7559 break;
Fred Drakec9680921999-12-13 16:37:25 +00007560 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007561 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007562 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007563 }
7564
7565 if (alt_grouplist != grouplist) {
7566 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007567 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007568
Fred Drakec9680921999-12-13 16:37:25 +00007569 return result;
7570}
Larry Hastings2f936352014-08-05 14:04:04 +10007571#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007572
Antoine Pitroub7572f02009-12-02 20:46:48 +00007573#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007574#ifdef __APPLE__
7575/*[clinic input]
7576os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007577
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007578 username as oname: FSConverter
7579 gid: int
7580 /
7581
7582Initialize the group access list.
7583
7584Call the system initgroups() to initialize the group access list with all of
7585the groups of which the specified username is a member, plus the specified
7586group id.
7587[clinic start generated code]*/
7588
Antoine Pitroub7572f02009-12-02 20:46:48 +00007589static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007590os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7591/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7592#else
7593/*[clinic input]
7594os.initgroups
7595
7596 username as oname: FSConverter
7597 gid: gid_t
7598 /
7599
7600Initialize the group access list.
7601
7602Call the system initgroups() to initialize the group access list with all of
7603the groups of which the specified username is a member, plus the specified
7604group id.
7605[clinic start generated code]*/
7606
7607static PyObject *
7608os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7609/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7610#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007611{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007612 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007613
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007614 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007615 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007616
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007617 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007618}
Larry Hastings2f936352014-08-05 14:04:04 +10007619#endif /* HAVE_INITGROUPS */
7620
Antoine Pitroub7572f02009-12-02 20:46:48 +00007621
Martin v. Löwis606edc12002-06-13 21:09:11 +00007622#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007623/*[clinic input]
7624os.getpgid
7625
7626 pid: pid_t
7627
7628Call the system call getpgid(), and return the result.
7629[clinic start generated code]*/
7630
Larry Hastings2f936352014-08-05 14:04:04 +10007631static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007632os_getpgid_impl(PyObject *module, pid_t pid)
7633/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007634{
7635 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007636 if (pgid < 0)
7637 return posix_error();
7638 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007639}
7640#endif /* HAVE_GETPGID */
7641
7642
Guido van Rossumb6775db1994-08-01 11:34:53 +00007643#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007644/*[clinic input]
7645os.getpgrp
7646
7647Return the current process group id.
7648[clinic start generated code]*/
7649
Larry Hastings2f936352014-08-05 14:04:04 +10007650static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007651os_getpgrp_impl(PyObject *module)
7652/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007653{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007654#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007655 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007656#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007657 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007658#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007659}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007660#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007662
Guido van Rossumb6775db1994-08-01 11:34:53 +00007663#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007664/*[clinic input]
7665os.setpgrp
7666
7667Make the current process the leader of its process group.
7668[clinic start generated code]*/
7669
Larry Hastings2f936352014-08-05 14:04:04 +10007670static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007671os_setpgrp_impl(PyObject *module)
7672/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007673{
Guido van Rossum64933891994-10-20 21:56:42 +00007674#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007675 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007676#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007677 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007678#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007679 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007680 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007681}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007682#endif /* HAVE_SETPGRP */
7683
Guido van Rossumad0ee831995-03-01 10:34:45 +00007684#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007685
7686#ifdef MS_WINDOWS
7687#include <tlhelp32.h>
7688
7689static PyObject*
7690win32_getppid()
7691{
7692 HANDLE snapshot;
7693 pid_t mypid;
7694 PyObject* result = NULL;
7695 BOOL have_record;
7696 PROCESSENTRY32 pe;
7697
7698 mypid = getpid(); /* This function never fails */
7699
7700 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7701 if (snapshot == INVALID_HANDLE_VALUE)
7702 return PyErr_SetFromWindowsErr(GetLastError());
7703
7704 pe.dwSize = sizeof(pe);
7705 have_record = Process32First(snapshot, &pe);
7706 while (have_record) {
7707 if (mypid == (pid_t)pe.th32ProcessID) {
7708 /* We could cache the ulong value in a static variable. */
7709 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7710 break;
7711 }
7712
7713 have_record = Process32Next(snapshot, &pe);
7714 }
7715
7716 /* If our loop exits and our pid was not found (result will be NULL)
7717 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7718 * error anyway, so let's raise it. */
7719 if (!result)
7720 result = PyErr_SetFromWindowsErr(GetLastError());
7721
7722 CloseHandle(snapshot);
7723
7724 return result;
7725}
7726#endif /*MS_WINDOWS*/
7727
Larry Hastings2f936352014-08-05 14:04:04 +10007728
7729/*[clinic input]
7730os.getppid
7731
7732Return the parent's process id.
7733
7734If the parent process has already exited, Windows machines will still
7735return its id; others systems will return the id of the 'init' process (1).
7736[clinic start generated code]*/
7737
Larry Hastings2f936352014-08-05 14:04:04 +10007738static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007739os_getppid_impl(PyObject *module)
7740/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007741{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007742#ifdef MS_WINDOWS
7743 return win32_getppid();
7744#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007746#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007747}
7748#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007749
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007750
Fred Drake12c6e2d1999-12-14 21:25:03 +00007751#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007752/*[clinic input]
7753os.getlogin
7754
7755Return the actual login name.
7756[clinic start generated code]*/
7757
Larry Hastings2f936352014-08-05 14:04:04 +10007758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007759os_getlogin_impl(PyObject *module)
7760/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007761{
Victor Stinner8c62be82010-05-06 00:08:46 +00007762 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007763#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007764 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007765 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007766
7767 if (GetUserNameW(user_name, &num_chars)) {
7768 /* num_chars is the number of unicode chars plus null terminator */
7769 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007770 }
7771 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007772 result = PyErr_SetFromWindowsErr(GetLastError());
7773#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 char *name;
7775 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007776
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 errno = 0;
7778 name = getlogin();
7779 if (name == NULL) {
7780 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007781 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007782 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007783 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 }
7785 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007786 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007787 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007788#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007789 return result;
7790}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007791#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007792
Larry Hastings2f936352014-08-05 14:04:04 +10007793
Guido van Rossumad0ee831995-03-01 10:34:45 +00007794#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007795/*[clinic input]
7796os.getuid
7797
7798Return the current process's user id.
7799[clinic start generated code]*/
7800
Larry Hastings2f936352014-08-05 14:04:04 +10007801static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007802os_getuid_impl(PyObject *module)
7803/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007804{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007805 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007806}
Larry Hastings2f936352014-08-05 14:04:04 +10007807#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007808
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007809
Brian Curtineb24d742010-04-12 17:16:38 +00007810#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007811#define HAVE_KILL
7812#endif /* MS_WINDOWS */
7813
7814#ifdef HAVE_KILL
7815/*[clinic input]
7816os.kill
7817
7818 pid: pid_t
7819 signal: Py_ssize_t
7820 /
7821
7822Kill a process with a signal.
7823[clinic start generated code]*/
7824
Larry Hastings2f936352014-08-05 14:04:04 +10007825static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007826os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7827/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007828{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007829 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7830 return NULL;
7831 }
7832#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007833 if (kill(pid, (int)signal) == -1)
7834 return posix_error();
7835 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007836#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007837 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007838 DWORD sig = (DWORD)signal;
7839 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007841
Victor Stinner8c62be82010-05-06 00:08:46 +00007842 /* Console processes which share a common console can be sent CTRL+C or
7843 CTRL+BREAK events, provided they handle said events. */
7844 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007845 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 err = GetLastError();
7847 PyErr_SetFromWindowsErr(err);
7848 }
7849 else
7850 Py_RETURN_NONE;
7851 }
Brian Curtineb24d742010-04-12 17:16:38 +00007852
Victor Stinner8c62be82010-05-06 00:08:46 +00007853 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7854 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007855 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007856 if (handle == NULL) {
7857 err = GetLastError();
7858 return PyErr_SetFromWindowsErr(err);
7859 }
Brian Curtineb24d742010-04-12 17:16:38 +00007860
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 if (TerminateProcess(handle, sig) == 0) {
7862 err = GetLastError();
7863 result = PyErr_SetFromWindowsErr(err);
7864 } else {
7865 Py_INCREF(Py_None);
7866 result = Py_None;
7867 }
Brian Curtineb24d742010-04-12 17:16:38 +00007868
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 CloseHandle(handle);
7870 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007871#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007872}
Larry Hastings2f936352014-08-05 14:04:04 +10007873#endif /* HAVE_KILL */
7874
7875
7876#ifdef HAVE_KILLPG
7877/*[clinic input]
7878os.killpg
7879
7880 pgid: pid_t
7881 signal: int
7882 /
7883
7884Kill a process group with a signal.
7885[clinic start generated code]*/
7886
Larry Hastings2f936352014-08-05 14:04:04 +10007887static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007888os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7889/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007890{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007891 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7892 return NULL;
7893 }
Larry Hastings2f936352014-08-05 14:04:04 +10007894 /* XXX some man pages make the `pgid` parameter an int, others
7895 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7896 take the same type. Moreover, pid_t is always at least as wide as
7897 int (else compilation of this module fails), which is safe. */
7898 if (killpg(pgid, signal) == -1)
7899 return posix_error();
7900 Py_RETURN_NONE;
7901}
7902#endif /* HAVE_KILLPG */
7903
Brian Curtineb24d742010-04-12 17:16:38 +00007904
Guido van Rossumc0125471996-06-28 18:55:32 +00007905#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007906#ifdef HAVE_SYS_LOCK_H
7907#include <sys/lock.h>
7908#endif
7909
Larry Hastings2f936352014-08-05 14:04:04 +10007910/*[clinic input]
7911os.plock
7912 op: int
7913 /
7914
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007915Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007916[clinic start generated code]*/
7917
Larry Hastings2f936352014-08-05 14:04:04 +10007918static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007919os_plock_impl(PyObject *module, int op)
7920/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007921{
Victor Stinner8c62be82010-05-06 00:08:46 +00007922 if (plock(op) == -1)
7923 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007924 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007925}
Larry Hastings2f936352014-08-05 14:04:04 +10007926#endif /* HAVE_PLOCK */
7927
Guido van Rossumc0125471996-06-28 18:55:32 +00007928
Guido van Rossumb6775db1994-08-01 11:34:53 +00007929#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007930/*[clinic input]
7931os.setuid
7932
7933 uid: uid_t
7934 /
7935
7936Set the current process's user id.
7937[clinic start generated code]*/
7938
Larry Hastings2f936352014-08-05 14:04:04 +10007939static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007940os_setuid_impl(PyObject *module, uid_t uid)
7941/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007942{
Victor Stinner8c62be82010-05-06 00:08:46 +00007943 if (setuid(uid) < 0)
7944 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007945 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007946}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007947#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007949
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007950#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007951/*[clinic input]
7952os.seteuid
7953
7954 euid: uid_t
7955 /
7956
7957Set the current process's effective user id.
7958[clinic start generated code]*/
7959
Larry Hastings2f936352014-08-05 14:04:04 +10007960static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007961os_seteuid_impl(PyObject *module, uid_t euid)
7962/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007963{
7964 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007965 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007966 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007967}
7968#endif /* HAVE_SETEUID */
7969
Larry Hastings2f936352014-08-05 14:04:04 +10007970
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007971#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007972/*[clinic input]
7973os.setegid
7974
7975 egid: gid_t
7976 /
7977
7978Set the current process's effective group id.
7979[clinic start generated code]*/
7980
Larry Hastings2f936352014-08-05 14:04:04 +10007981static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007982os_setegid_impl(PyObject *module, gid_t egid)
7983/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007984{
7985 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007987 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007988}
7989#endif /* HAVE_SETEGID */
7990
Larry Hastings2f936352014-08-05 14:04:04 +10007991
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007992#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007993/*[clinic input]
7994os.setreuid
7995
7996 ruid: uid_t
7997 euid: uid_t
7998 /
7999
8000Set the current process's real and effective user ids.
8001[clinic start generated code]*/
8002
Larry Hastings2f936352014-08-05 14:04:04 +10008003static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008004os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
8005/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008006{
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 if (setreuid(ruid, euid) < 0) {
8008 return posix_error();
8009 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008010 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00008011 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008012}
8013#endif /* HAVE_SETREUID */
8014
Larry Hastings2f936352014-08-05 14:04:04 +10008015
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008016#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10008017/*[clinic input]
8018os.setregid
8019
8020 rgid: gid_t
8021 egid: gid_t
8022 /
8023
8024Set the current process's real and effective group ids.
8025[clinic start generated code]*/
8026
Larry Hastings2f936352014-08-05 14:04:04 +10008027static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008028os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
8029/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008030{
8031 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008033 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008034}
8035#endif /* HAVE_SETREGID */
8036
Larry Hastings2f936352014-08-05 14:04:04 +10008037
Guido van Rossumb6775db1994-08-01 11:34:53 +00008038#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10008039/*[clinic input]
8040os.setgid
8041 gid: gid_t
8042 /
8043
8044Set the current process's group id.
8045[clinic start generated code]*/
8046
Larry Hastings2f936352014-08-05 14:04:04 +10008047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008048os_setgid_impl(PyObject *module, gid_t gid)
8049/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008050{
Victor Stinner8c62be82010-05-06 00:08:46 +00008051 if (setgid(gid) < 0)
8052 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008053 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008054}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008055#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008056
Larry Hastings2f936352014-08-05 14:04:04 +10008057
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008058#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10008059/*[clinic input]
8060os.setgroups
8061
8062 groups: object
8063 /
8064
8065Set the groups of the current process to list.
8066[clinic start generated code]*/
8067
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008069os_setgroups(PyObject *module, PyObject *groups)
8070/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008071{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008072 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00008073 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00008074
Victor Stinner8c62be82010-05-06 00:08:46 +00008075 if (!PySequence_Check(groups)) {
8076 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
8077 return NULL;
8078 }
8079 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008080 if (len < 0) {
8081 return NULL;
8082 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008083 if (len > MAX_GROUPS) {
8084 PyErr_SetString(PyExc_ValueError, "too many groups");
8085 return NULL;
8086 }
8087 for(i = 0; i < len; i++) {
8088 PyObject *elem;
8089 elem = PySequence_GetItem(groups, i);
8090 if (!elem)
8091 return NULL;
8092 if (!PyLong_Check(elem)) {
8093 PyErr_SetString(PyExc_TypeError,
8094 "groups must be integers");
8095 Py_DECREF(elem);
8096 return NULL;
8097 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008098 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008099 Py_DECREF(elem);
8100 return NULL;
8101 }
8102 }
8103 Py_DECREF(elem);
8104 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008105
Victor Stinner8c62be82010-05-06 00:08:46 +00008106 if (setgroups(len, grouplist) < 0)
8107 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008108 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008109}
8110#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008111
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008112#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
8113static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008114wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008115{
Victor Stinner8c62be82010-05-06 00:08:46 +00008116 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08008117 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008118
Victor Stinner8c62be82010-05-06 00:08:46 +00008119 if (pid == -1)
8120 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008121
Zackery Spytz682107c2019-09-09 09:48:32 -06008122 // If wait succeeded but no child was ready to report status, ru will not
8123 // have been populated.
8124 if (pid == 0) {
8125 memset(ru, 0, sizeof(*ru));
8126 }
8127
Eddie Elizondob3966632019-11-05 07:16:14 -08008128 PyObject *m = PyImport_ImportModuleNoBlock("resource");
8129 if (m == NULL)
8130 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02008131 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08008132 Py_DECREF(m);
8133 if (struct_rusage == NULL)
8134 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008135
Victor Stinner8c62be82010-05-06 00:08:46 +00008136 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
8137 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08008138 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00008139 if (!result)
8140 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008141
8142#ifndef doubletime
8143#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
8144#endif
8145
Victor Stinner8c62be82010-05-06 00:08:46 +00008146 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008147 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00008148 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008149 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008150#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00008151 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
8152 SET_INT(result, 2, ru->ru_maxrss);
8153 SET_INT(result, 3, ru->ru_ixrss);
8154 SET_INT(result, 4, ru->ru_idrss);
8155 SET_INT(result, 5, ru->ru_isrss);
8156 SET_INT(result, 6, ru->ru_minflt);
8157 SET_INT(result, 7, ru->ru_majflt);
8158 SET_INT(result, 8, ru->ru_nswap);
8159 SET_INT(result, 9, ru->ru_inblock);
8160 SET_INT(result, 10, ru->ru_oublock);
8161 SET_INT(result, 11, ru->ru_msgsnd);
8162 SET_INT(result, 12, ru->ru_msgrcv);
8163 SET_INT(result, 13, ru->ru_nsignals);
8164 SET_INT(result, 14, ru->ru_nvcsw);
8165 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008166#undef SET_INT
8167
Victor Stinner8c62be82010-05-06 00:08:46 +00008168 if (PyErr_Occurred()) {
8169 Py_DECREF(result);
8170 return NULL;
8171 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008172
Victor Stinner8c62be82010-05-06 00:08:46 +00008173 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008174}
8175#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
8176
Larry Hastings2f936352014-08-05 14:04:04 +10008177
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008178#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10008179/*[clinic input]
8180os.wait3
8181
8182 options: int
8183Wait for completion of a child process.
8184
8185Returns a tuple of information about the child process:
8186 (pid, status, rusage)
8187[clinic start generated code]*/
8188
Larry Hastings2f936352014-08-05 14:04:04 +10008189static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008190os_wait3_impl(PyObject *module, int options)
8191/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008192{
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008195 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008196 WAIT_TYPE status;
8197 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008198
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008199 do {
8200 Py_BEGIN_ALLOW_THREADS
8201 pid = wait3(&status, options, &ru);
8202 Py_END_ALLOW_THREADS
8203 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8204 if (pid < 0)
8205 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008206
Victor Stinner1c2fa782020-05-10 11:05:29 +02008207 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008208}
8209#endif /* HAVE_WAIT3 */
8210
Larry Hastings2f936352014-08-05 14:04:04 +10008211
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008212#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10008213/*[clinic input]
8214
8215os.wait4
8216
8217 pid: pid_t
8218 options: int
8219
8220Wait for completion of a specific child process.
8221
8222Returns a tuple of information about the child process:
8223 (pid, status, rusage)
8224[clinic start generated code]*/
8225
Larry Hastings2f936352014-08-05 14:04:04 +10008226static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008227os_wait4_impl(PyObject *module, pid_t pid, int options)
8228/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008229{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008230 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008231 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008232 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008233 WAIT_TYPE status;
8234 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008235
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008236 do {
8237 Py_BEGIN_ALLOW_THREADS
8238 res = wait4(pid, &status, options, &ru);
8239 Py_END_ALLOW_THREADS
8240 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8241 if (res < 0)
8242 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008243
Victor Stinner1c2fa782020-05-10 11:05:29 +02008244 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008245}
8246#endif /* HAVE_WAIT4 */
8247
Larry Hastings2f936352014-08-05 14:04:04 +10008248
Ross Lagerwall7807c352011-03-17 20:20:30 +02008249#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10008250/*[clinic input]
8251os.waitid
8252
8253 idtype: idtype_t
8254 Must be one of be P_PID, P_PGID or P_ALL.
8255 id: id_t
8256 The id to wait on.
8257 options: int
8258 Constructed from the ORing of one or more of WEXITED, WSTOPPED
8259 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
8260 /
8261
8262Returns the result of waiting for a process or processes.
8263
8264Returns either waitid_result or None if WNOHANG is specified and there are
8265no children in a waitable state.
8266[clinic start generated code]*/
8267
Larry Hastings2f936352014-08-05 14:04:04 +10008268static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008269os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
8270/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008271{
8272 PyObject *result;
8273 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008274 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008275 siginfo_t si;
8276 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008277
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008278 do {
8279 Py_BEGIN_ALLOW_THREADS
8280 res = waitid(idtype, id, &si, options);
8281 Py_END_ALLOW_THREADS
8282 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8283 if (res < 0)
8284 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008285
8286 if (si.si_pid == 0)
8287 Py_RETURN_NONE;
8288
Hai Shif707d942020-03-16 21:15:01 +08008289 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008290 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008291 if (!result)
8292 return NULL;
8293
8294 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008295 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008296 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
8297 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
8298 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
8299 if (PyErr_Occurred()) {
8300 Py_DECREF(result);
8301 return NULL;
8302 }
8303
8304 return result;
8305}
Larry Hastings2f936352014-08-05 14:04:04 +10008306#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008307
Larry Hastings2f936352014-08-05 14:04:04 +10008308
8309#if defined(HAVE_WAITPID)
8310/*[clinic input]
8311os.waitpid
8312 pid: pid_t
8313 options: int
8314 /
8315
8316Wait for completion of a given child process.
8317
8318Returns a tuple of information regarding the child process:
8319 (pid, status)
8320
8321The options argument is ignored on Windows.
8322[clinic start generated code]*/
8323
Larry Hastings2f936352014-08-05 14:04:04 +10008324static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008325os_waitpid_impl(PyObject *module, pid_t pid, int options)
8326/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008327{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008328 pid_t res;
8329 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008330 WAIT_TYPE status;
8331 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008332
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008333 do {
8334 Py_BEGIN_ALLOW_THREADS
8335 res = waitpid(pid, &status, options);
8336 Py_END_ALLOW_THREADS
8337 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8338 if (res < 0)
8339 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008340
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008341 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00008342}
Tim Petersab034fa2002-02-01 11:27:43 +00008343#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00008344/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10008345/*[clinic input]
8346os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07008347 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10008348 options: int
8349 /
8350
8351Wait for completion of a given process.
8352
8353Returns a tuple of information regarding the process:
8354 (pid, status << 8)
8355
8356The options argument is ignored on Windows.
8357[clinic start generated code]*/
8358
Larry Hastings2f936352014-08-05 14:04:04 +10008359static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07008360os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07008361/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008362{
8363 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07008364 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008365 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008366
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008367 do {
8368 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08008369 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008370 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08008371 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008372 Py_END_ALLOW_THREADS
8373 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008374 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008375 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008376
Victor Stinner9bee32b2020-04-22 16:30:35 +02008377 unsigned long long ustatus = (unsigned int)status;
8378
Victor Stinner8c62be82010-05-06 00:08:46 +00008379 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02008380 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00008381}
Larry Hastings2f936352014-08-05 14:04:04 +10008382#endif
8383
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008384
Guido van Rossumad0ee831995-03-01 10:34:45 +00008385#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10008386/*[clinic input]
8387os.wait
8388
8389Wait for completion of a child process.
8390
8391Returns a tuple of information about the child process:
8392 (pid, status)
8393[clinic start generated code]*/
8394
Larry Hastings2f936352014-08-05 14:04:04 +10008395static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008396os_wait_impl(PyObject *module)
8397/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008398{
Victor Stinner8c62be82010-05-06 00:08:46 +00008399 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008400 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008401 WAIT_TYPE status;
8402 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008403
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008404 do {
8405 Py_BEGIN_ALLOW_THREADS
8406 pid = wait(&status);
8407 Py_END_ALLOW_THREADS
8408 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8409 if (pid < 0)
8410 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008411
Victor Stinner8c62be82010-05-06 00:08:46 +00008412 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008413}
Larry Hastings2f936352014-08-05 14:04:04 +10008414#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008415
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008416#if defined(__linux__) && defined(__NR_pidfd_open)
8417/*[clinic input]
8418os.pidfd_open
8419 pid: pid_t
8420 flags: unsigned_int = 0
8421
8422Return a file descriptor referring to the process *pid*.
8423
8424The descriptor can be used to perform process management without races and
8425signals.
8426[clinic start generated code]*/
8427
8428static PyObject *
8429os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8430/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8431{
8432 int fd = syscall(__NR_pidfd_open, pid, flags);
8433 if (fd < 0) {
8434 return posix_error();
8435 }
8436 return PyLong_FromLong(fd);
8437}
8438#endif
8439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008440
Larry Hastings9cf065c2012-06-22 16:30:09 -07008441#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008442/*[clinic input]
8443os.readlink
8444
8445 path: path_t
8446 *
8447 dir_fd: dir_fd(requires='readlinkat') = None
8448
8449Return a string representing the path to which the symbolic link points.
8450
8451If dir_fd is not None, it should be a file descriptor open to a directory,
8452and path should be relative; path will then be relative to that directory.
8453
8454dir_fd may not be implemented on your platform. If it is unavailable,
8455using it will raise a NotImplementedError.
8456[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008457
Barry Warsaw53699e91996-12-10 23:23:01 +00008458static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008459os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8460/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008461{
Berker Peksage0b5b202018-08-15 13:03:41 +03008462#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008463 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008464 ssize_t length;
Ronald Oussoren41761932020-11-08 10:05:27 +01008465#ifdef HAVE_READLINKAT
8466 int readlinkat_unavailable = 0;
8467#endif
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008468
8469 Py_BEGIN_ALLOW_THREADS
8470#ifdef HAVE_READLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01008471 if (dir_fd != DEFAULT_DIR_FD) {
8472 if (HAVE_READLINKAT_RUNTIME) {
8473 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8474 } else {
8475 readlinkat_unavailable = 1;
8476 }
8477 } else
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008478#endif
8479 length = readlink(path->narrow, buffer, MAXPATHLEN);
8480 Py_END_ALLOW_THREADS
8481
Ronald Oussoren41761932020-11-08 10:05:27 +01008482#ifdef HAVE_READLINKAT
8483 if (readlinkat_unavailable) {
8484 argument_unavailable_error(NULL, "dir_fd");
8485 return NULL;
8486 }
8487#endif
8488
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008489 if (length < 0) {
8490 return path_error(path);
8491 }
8492 buffer[length] = '\0';
8493
8494 if (PyUnicode_Check(path->object))
8495 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8496 else
8497 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008498#elif defined(MS_WINDOWS)
8499 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008500 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008501 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008502 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8503 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008504 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008505
Larry Hastings2f936352014-08-05 14:04:04 +10008506 /* First get a handle to the reparse point */
8507 Py_BEGIN_ALLOW_THREADS
8508 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008509 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008510 0,
8511 0,
8512 0,
8513 OPEN_EXISTING,
8514 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8515 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008516 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8517 /* New call DeviceIoControl to read the reparse point */
8518 io_result = DeviceIoControl(
8519 reparse_point_handle,
8520 FSCTL_GET_REPARSE_POINT,
8521 0, 0, /* in buffer */
8522 target_buffer, sizeof(target_buffer),
8523 &n_bytes_returned,
8524 0 /* we're not using OVERLAPPED_IO */
8525 );
8526 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008527 }
Larry Hastings2f936352014-08-05 14:04:04 +10008528 Py_END_ALLOW_THREADS
8529
Berker Peksage0b5b202018-08-15 13:03:41 +03008530 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008531 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008532 }
Larry Hastings2f936352014-08-05 14:04:04 +10008533
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008534 wchar_t *name = NULL;
8535 Py_ssize_t nameLen = 0;
8536 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008537 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008538 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8539 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8540 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008541 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008542 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8543 {
8544 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8545 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8546 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8547 }
8548 else
8549 {
8550 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8551 }
8552 if (name) {
8553 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8554 /* Our buffer is mutable, so this is okay */
8555 name[1] = L'\\';
8556 }
8557 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008558 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008559 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8560 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008561 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008562 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008563#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008564}
Berker Peksage0b5b202018-08-15 13:03:41 +03008565#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008566
Larry Hastings9cf065c2012-06-22 16:30:09 -07008567#if defined(MS_WINDOWS)
8568
Steve Dower6921e732018-03-05 14:26:08 -08008569/* Remove the last portion of the path - return 0 on success */
8570static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008571_dirnameW(WCHAR *path)
8572{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008573 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008574 size_t length = wcsnlen_s(path, MAX_PATH);
8575 if (length == MAX_PATH) {
8576 return -1;
8577 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008578
8579 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008580 for(ptr = path + length; ptr != path; ptr--) {
8581 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008582 break;
Steve Dower6921e732018-03-05 14:26:08 -08008583 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008584 }
8585 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008586 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008587}
8588
Minmin Gong7f21c9a2020-05-18 09:17:19 -07008589#endif
8590
8591#ifdef HAVE_SYMLINK
8592
8593#if defined(MS_WINDOWS)
8594
Victor Stinner31b3b922013-06-05 01:49:17 +02008595/* Is this path absolute? */
8596static int
8597_is_absW(const WCHAR *path)
8598{
Steve Dower6921e732018-03-05 14:26:08 -08008599 return path[0] == L'\\' || path[0] == L'/' ||
8600 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008601}
8602
Steve Dower6921e732018-03-05 14:26:08 -08008603/* join root and rest with a backslash - return 0 on success */
8604static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008605_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8606{
Victor Stinner31b3b922013-06-05 01:49:17 +02008607 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008608 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008609 }
8610
Steve Dower6921e732018-03-05 14:26:08 -08008611 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8612 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008613 }
Steve Dower6921e732018-03-05 14:26:08 -08008614
8615 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8616 return -1;
8617 }
8618
8619 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008620}
8621
Victor Stinner31b3b922013-06-05 01:49:17 +02008622/* Return True if the path at src relative to dest is a directory */
8623static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008624_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008625{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008626 WIN32_FILE_ATTRIBUTE_DATA src_info;
8627 WCHAR dest_parent[MAX_PATH];
8628 WCHAR src_resolved[MAX_PATH] = L"";
8629
8630 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008631 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8632 _dirnameW(dest_parent)) {
8633 return 0;
8634 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008635 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008636 if (_joinW(src_resolved, dest_parent, src)) {
8637 return 0;
8638 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008639 return (
8640 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8641 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8642 );
8643}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008644#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008645
Larry Hastings2f936352014-08-05 14:04:04 +10008646
8647/*[clinic input]
8648os.symlink
8649 src: path_t
8650 dst: path_t
8651 target_is_directory: bool = False
8652 *
8653 dir_fd: dir_fd(requires='symlinkat')=None
8654
8655# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8656
8657Create a symbolic link pointing to src named dst.
8658
8659target_is_directory is required on Windows if the target is to be
8660 interpreted as a directory. (On Windows, symlink requires
8661 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8662 target_is_directory is ignored on non-Windows platforms.
8663
8664If dir_fd is not None, it should be a file descriptor open to a directory,
8665 and path should be relative; path will then be relative to that directory.
8666dir_fd may not be implemented on your platform.
8667 If it is unavailable, using it will raise a NotImplementedError.
8668
8669[clinic start generated code]*/
8670
Larry Hastings2f936352014-08-05 14:04:04 +10008671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008672os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008673 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008674/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008675{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008676#ifdef MS_WINDOWS
8677 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008678 DWORD flags = 0;
8679
8680 /* Assumed true, set to false if detected to not be available. */
8681 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008682#else
8683 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01008684#ifdef HAVE_SYMLINKAT
8685 int symlinkat_unavailable = 0;
8686#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07008687#endif
8688
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008689 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8690 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8691 return NULL;
8692 }
8693
Larry Hastings9cf065c2012-06-22 16:30:09 -07008694#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008695
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008696 if (windows_has_symlink_unprivileged_flag) {
8697 /* Allow non-admin symlinks if system allows it. */
8698 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8699 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008700
Larry Hastings9cf065c2012-06-22 16:30:09 -07008701 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008702 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008703 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8704 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8705 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8706 }
8707
8708 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008709 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008710 Py_END_ALLOW_THREADS
8711
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008712 if (windows_has_symlink_unprivileged_flag && !result &&
8713 ERROR_INVALID_PARAMETER == GetLastError()) {
8714
8715 Py_BEGIN_ALLOW_THREADS
8716 _Py_BEGIN_SUPPRESS_IPH
8717 /* This error might be caused by
8718 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8719 Try again, and update windows_has_symlink_unprivileged_flag if we
8720 are successful this time.
8721
8722 NOTE: There is a risk of a race condition here if there are other
8723 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8724 another process (or thread) changes that condition in between our
8725 calls to CreateSymbolicLink.
8726 */
8727 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8728 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8729 _Py_END_SUPPRESS_IPH
8730 Py_END_ALLOW_THREADS
8731
8732 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8733 windows_has_symlink_unprivileged_flag = FALSE;
8734 }
8735 }
8736
Larry Hastings2f936352014-08-05 14:04:04 +10008737 if (!result)
8738 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008739
8740#else
8741
Steve Dower6921e732018-03-05 14:26:08 -08008742 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8743 PyErr_SetString(PyExc_ValueError,
8744 "symlink: src and dst must be the same type");
8745 return NULL;
8746 }
8747
Larry Hastings9cf065c2012-06-22 16:30:09 -07008748 Py_BEGIN_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01008749#ifdef HAVE_SYMLINKAT
8750 if (dir_fd != DEFAULT_DIR_FD) {
8751 if (HAVE_SYMLINKAT_RUNTIME) {
8752 result = symlinkat(src->narrow, dir_fd, dst->narrow);
8753 } else {
8754 symlinkat_unavailable = 1;
8755 }
8756 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008757#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008758 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008759 Py_END_ALLOW_THREADS
8760
Ronald Oussoren41761932020-11-08 10:05:27 +01008761#ifdef HAVE_SYMLINKAT
8762 if (symlinkat_unavailable) {
8763 argument_unavailable_error(NULL, "dir_fd");
8764 return NULL;
8765 }
8766#endif
8767
Larry Hastings2f936352014-08-05 14:04:04 +10008768 if (result)
8769 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008770#endif
8771
Larry Hastings2f936352014-08-05 14:04:04 +10008772 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008773}
8774#endif /* HAVE_SYMLINK */
8775
Larry Hastings9cf065c2012-06-22 16:30:09 -07008776
Brian Curtind40e6f72010-07-08 21:39:08 +00008777
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008778
Larry Hastings605a62d2012-06-24 04:33:36 -07008779static PyStructSequence_Field times_result_fields[] = {
8780 {"user", "user time"},
8781 {"system", "system time"},
8782 {"children_user", "user time of children"},
8783 {"children_system", "system time of children"},
8784 {"elapsed", "elapsed time since an arbitrary point in the past"},
8785 {NULL}
8786};
8787
8788PyDoc_STRVAR(times_result__doc__,
8789"times_result: Result from os.times().\n\n\
8790This object may be accessed either as a tuple of\n\
8791 (user, system, children_user, children_system, elapsed),\n\
8792or via the attributes user, system, children_user, children_system,\n\
8793and elapsed.\n\
8794\n\
8795See os.times for more information.");
8796
8797static PyStructSequence_Desc times_result_desc = {
8798 "times_result", /* name */
8799 times_result__doc__, /* doc */
8800 times_result_fields,
8801 5
8802};
8803
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008804#ifdef MS_WINDOWS
8805#define HAVE_TIMES /* mandatory, for the method table */
8806#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008807
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008808#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008809
8810static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008811build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008812 double children_user, double children_system,
8813 double elapsed)
8814{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008815 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008816 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008817 if (value == NULL)
8818 return NULL;
8819
8820#define SET(i, field) \
8821 { \
8822 PyObject *o = PyFloat_FromDouble(field); \
8823 if (!o) { \
8824 Py_DECREF(value); \
8825 return NULL; \
8826 } \
8827 PyStructSequence_SET_ITEM(value, i, o); \
8828 } \
8829
8830 SET(0, user);
8831 SET(1, system);
8832 SET(2, children_user);
8833 SET(3, children_system);
8834 SET(4, elapsed);
8835
8836#undef SET
8837
8838 return value;
8839}
8840
Larry Hastings605a62d2012-06-24 04:33:36 -07008841
Larry Hastings2f936352014-08-05 14:04:04 +10008842#ifndef MS_WINDOWS
8843#define NEED_TICKS_PER_SECOND
8844static long ticks_per_second = -1;
8845#endif /* MS_WINDOWS */
8846
8847/*[clinic input]
8848os.times
8849
8850Return a collection containing process timing information.
8851
8852The object returned behaves like a named tuple with these fields:
8853 (utime, stime, cutime, cstime, elapsed_time)
8854All fields are floating point numbers.
8855[clinic start generated code]*/
8856
Larry Hastings2f936352014-08-05 14:04:04 +10008857static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008858os_times_impl(PyObject *module)
8859/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008860#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008861{
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 FILETIME create, exit, kernel, user;
8863 HANDLE hProc;
8864 hProc = GetCurrentProcess();
8865 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8866 /* The fields of a FILETIME structure are the hi and lo part
8867 of a 64-bit value expressed in 100 nanosecond units.
8868 1e7 is one second in such units; 1e-7 the inverse.
8869 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8870 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008871 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008872 (double)(user.dwHighDateTime*429.4967296 +
8873 user.dwLowDateTime*1e-7),
8874 (double)(kernel.dwHighDateTime*429.4967296 +
8875 kernel.dwLowDateTime*1e-7),
8876 (double)0,
8877 (double)0,
8878 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008879}
Larry Hastings2f936352014-08-05 14:04:04 +10008880#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008881{
Larry Hastings2f936352014-08-05 14:04:04 +10008882
8883
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008884 struct tms t;
8885 clock_t c;
8886 errno = 0;
8887 c = times(&t);
8888 if (c == (clock_t) -1)
8889 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008890 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008891 (double)t.tms_utime / ticks_per_second,
8892 (double)t.tms_stime / ticks_per_second,
8893 (double)t.tms_cutime / ticks_per_second,
8894 (double)t.tms_cstime / ticks_per_second,
8895 (double)c / ticks_per_second);
8896}
Larry Hastings2f936352014-08-05 14:04:04 +10008897#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008898#endif /* HAVE_TIMES */
8899
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008900
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008901#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008902/*[clinic input]
8903os.getsid
8904
8905 pid: pid_t
8906 /
8907
8908Call the system call getsid(pid) and return the result.
8909[clinic start generated code]*/
8910
Larry Hastings2f936352014-08-05 14:04:04 +10008911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008912os_getsid_impl(PyObject *module, pid_t pid)
8913/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008914{
Victor Stinner8c62be82010-05-06 00:08:46 +00008915 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 sid = getsid(pid);
8917 if (sid < 0)
8918 return posix_error();
8919 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008920}
8921#endif /* HAVE_GETSID */
8922
8923
Guido van Rossumb6775db1994-08-01 11:34:53 +00008924#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008925/*[clinic input]
8926os.setsid
8927
8928Call the system call setsid().
8929[clinic start generated code]*/
8930
Larry Hastings2f936352014-08-05 14:04:04 +10008931static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008932os_setsid_impl(PyObject *module)
8933/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008934{
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 if (setsid() < 0)
8936 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008937 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008938}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008939#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008940
Larry Hastings2f936352014-08-05 14:04:04 +10008941
Guido van Rossumb6775db1994-08-01 11:34:53 +00008942#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008943/*[clinic input]
8944os.setpgid
8945
8946 pid: pid_t
8947 pgrp: pid_t
8948 /
8949
8950Call the system call setpgid(pid, pgrp).
8951[clinic start generated code]*/
8952
Larry Hastings2f936352014-08-05 14:04:04 +10008953static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008954os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8955/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008956{
Victor Stinner8c62be82010-05-06 00:08:46 +00008957 if (setpgid(pid, pgrp) < 0)
8958 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008959 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008960}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008961#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008962
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008963
Guido van Rossumb6775db1994-08-01 11:34:53 +00008964#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008965/*[clinic input]
8966os.tcgetpgrp
8967
8968 fd: int
8969 /
8970
8971Return the process group associated with the terminal specified by fd.
8972[clinic start generated code]*/
8973
Larry Hastings2f936352014-08-05 14:04:04 +10008974static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008975os_tcgetpgrp_impl(PyObject *module, int fd)
8976/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008977{
8978 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 if (pgid < 0)
8980 return posix_error();
8981 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008982}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008983#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008984
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008985
Guido van Rossumb6775db1994-08-01 11:34:53 +00008986#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008987/*[clinic input]
8988os.tcsetpgrp
8989
8990 fd: int
8991 pgid: pid_t
8992 /
8993
8994Set the process group associated with the terminal specified by fd.
8995[clinic start generated code]*/
8996
Larry Hastings2f936352014-08-05 14:04:04 +10008997static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008998os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
8999/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009000{
Victor Stinner8c62be82010-05-06 00:08:46 +00009001 if (tcsetpgrp(fd, pgid) < 0)
9002 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009003 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00009004}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009005#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00009006
Guido van Rossum687dd131993-05-17 08:34:16 +00009007/* Functions acting on file descriptors */
9008
Victor Stinnerdaf45552013-08-28 00:53:59 +02009009#ifdef O_CLOEXEC
9010extern int _Py_open_cloexec_works;
9011#endif
9012
Larry Hastings2f936352014-08-05 14:04:04 +10009013
9014/*[clinic input]
9015os.open -> int
9016 path: path_t
9017 flags: int
9018 mode: int = 0o777
9019 *
9020 dir_fd: dir_fd(requires='openat') = None
9021
9022# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
9023
9024Open a file for low level IO. Returns a file descriptor (integer).
9025
9026If dir_fd is not None, it should be a file descriptor open to a directory,
9027 and path should be relative; path will then be relative to that directory.
9028dir_fd may not be implemented on your platform.
9029 If it is unavailable, using it will raise a NotImplementedError.
9030[clinic start generated code]*/
9031
Larry Hastings2f936352014-08-05 14:04:04 +10009032static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009033os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
9034/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009035{
9036 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009037 int async_err = 0;
Ronald Oussoren41761932020-11-08 10:05:27 +01009038#ifdef HAVE_OPENAT
9039 int openat_unavailable = 0;
9040#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009041
Victor Stinnerdaf45552013-08-28 00:53:59 +02009042#ifdef O_CLOEXEC
9043 int *atomic_flag_works = &_Py_open_cloexec_works;
9044#elif !defined(MS_WINDOWS)
9045 int *atomic_flag_works = NULL;
9046#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00009047
Victor Stinnerdaf45552013-08-28 00:53:59 +02009048#ifdef MS_WINDOWS
9049 flags |= O_NOINHERIT;
9050#elif defined(O_CLOEXEC)
9051 flags |= O_CLOEXEC;
9052#endif
9053
Steve Dowerb82e17e2019-05-23 08:45:22 -07009054 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
9055 return -1;
9056 }
9057
Steve Dower8fc89802015-04-12 00:26:27 -04009058 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009059 do {
9060 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07009061#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009062 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009063#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07009064#ifdef HAVE_OPENAT
Ronald Oussoren41761932020-11-08 10:05:27 +01009065 if (dir_fd != DEFAULT_DIR_FD) {
9066 if (HAVE_OPENAT_RUNTIME) {
9067 fd = openat(dir_fd, path->narrow, flags, mode);
9068
9069 } else {
9070 openat_unavailable = 1;
9071 fd = -1;
9072 }
9073 } else
Steve Dower6230aaf2016-09-09 09:03:15 -07009074#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009075 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009076#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009077 Py_END_ALLOW_THREADS
9078 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009079 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00009080
Ronald Oussoren41761932020-11-08 10:05:27 +01009081#ifdef HAVE_OPENAT
9082 if (openat_unavailable) {
9083 argument_unavailable_error(NULL, "dir_fd");
9084 return -1;
9085 }
9086#endif
9087
Victor Stinnerd3ffd322015-09-15 10:11:03 +02009088 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009089 if (!async_err)
9090 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10009091 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009092 }
9093
Victor Stinnerdaf45552013-08-28 00:53:59 +02009094#ifndef MS_WINDOWS
9095 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
9096 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10009097 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009098 }
9099#endif
9100
Larry Hastings2f936352014-08-05 14:04:04 +10009101 return fd;
9102}
9103
9104
9105/*[clinic input]
9106os.close
9107
9108 fd: int
9109
9110Close a file descriptor.
9111[clinic start generated code]*/
9112
Barry Warsaw53699e91996-12-10 23:23:01 +00009113static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009114os_close_impl(PyObject *module, int fd)
9115/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009116{
Larry Hastings2f936352014-08-05 14:04:04 +10009117 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009118 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
9119 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
9120 * for more details.
9121 */
Victor Stinner8c62be82010-05-06 00:08:46 +00009122 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009123 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009124 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04009125 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 Py_END_ALLOW_THREADS
9127 if (res < 0)
9128 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009129 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00009130}
9131
Larry Hastings2f936352014-08-05 14:04:04 +10009132/*[clinic input]
9133os.closerange
9134
9135 fd_low: int
9136 fd_high: int
9137 /
9138
9139Closes all file descriptors in [fd_low, fd_high), ignoring errors.
9140[clinic start generated code]*/
9141
Larry Hastings2f936352014-08-05 14:04:04 +10009142static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009143os_closerange_impl(PyObject *module, int fd_low, int fd_high)
9144/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009145{
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 Py_BEGIN_ALLOW_THREADS
Kyle Evansc230fde2020-10-11 13:54:11 -05009147 _Py_closerange(fd_low, fd_high - 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00009148 Py_END_ALLOW_THREADS
9149 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00009150}
9151
9152
Larry Hastings2f936352014-08-05 14:04:04 +10009153/*[clinic input]
9154os.dup -> int
9155
9156 fd: int
9157 /
9158
9159Return a duplicate of a file descriptor.
9160[clinic start generated code]*/
9161
Larry Hastings2f936352014-08-05 14:04:04 +10009162static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009163os_dup_impl(PyObject *module, int fd)
9164/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009165{
9166 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00009167}
9168
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009169
Larry Hastings2f936352014-08-05 14:04:04 +10009170/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009171os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10009172 fd: int
9173 fd2: int
9174 inheritable: bool=True
9175
9176Duplicate file descriptor.
9177[clinic start generated code]*/
9178
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009179static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009180os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009181/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009182{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01009183 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009184#if defined(HAVE_DUP3) && \
9185 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
9186 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03009187 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009188#endif
9189
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009190 if (fd < 0 || fd2 < 0) {
9191 posix_error();
9192 return -1;
9193 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009194
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009195 /* dup2() can fail with EINTR if the target FD is already open, because it
9196 * then has to be closed. See os_close_impl() for why we don't handle EINTR
9197 * upon close(), and therefore below.
9198 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02009199#ifdef MS_WINDOWS
9200 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009201 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04009203 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009204 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009205 if (res < 0) {
9206 posix_error();
9207 return -1;
9208 }
9209 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02009210
9211 /* Character files like console cannot be make non-inheritable */
9212 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9213 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009214 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009215 }
9216
9217#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
9218 Py_BEGIN_ALLOW_THREADS
9219 if (!inheritable)
9220 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
9221 else
9222 res = dup2(fd, fd2);
9223 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009224 if (res < 0) {
9225 posix_error();
9226 return -1;
9227 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009228
9229#else
9230
9231#ifdef HAVE_DUP3
9232 if (!inheritable && dup3_works != 0) {
9233 Py_BEGIN_ALLOW_THREADS
9234 res = dup3(fd, fd2, O_CLOEXEC);
9235 Py_END_ALLOW_THREADS
9236 if (res < 0) {
9237 if (dup3_works == -1)
9238 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009239 if (dup3_works) {
9240 posix_error();
9241 return -1;
9242 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009243 }
9244 }
9245
9246 if (inheritable || dup3_works == 0)
9247 {
9248#endif
9249 Py_BEGIN_ALLOW_THREADS
9250 res = dup2(fd, fd2);
9251 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009252 if (res < 0) {
9253 posix_error();
9254 return -1;
9255 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009256
9257 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9258 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009259 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009260 }
9261#ifdef HAVE_DUP3
9262 }
9263#endif
9264
9265#endif
9266
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009267 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00009268}
9269
Larry Hastings2f936352014-08-05 14:04:04 +10009270
Ross Lagerwall7807c352011-03-17 20:20:30 +02009271#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10009272/*[clinic input]
9273os.lockf
9274
9275 fd: int
9276 An open file descriptor.
9277 command: int
9278 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
9279 length: Py_off_t
9280 The number of bytes to lock, starting at the current position.
9281 /
9282
9283Apply, test or remove a POSIX lock on an open file descriptor.
9284
9285[clinic start generated code]*/
9286
Larry Hastings2f936352014-08-05 14:04:04 +10009287static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009288os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
9289/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009290{
9291 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009292
Saiyang Gou7514f4f2020-02-12 23:47:42 -08009293 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
9294 return NULL;
9295 }
9296
Ross Lagerwall7807c352011-03-17 20:20:30 +02009297 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009298 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009299 Py_END_ALLOW_THREADS
9300
9301 if (res < 0)
9302 return posix_error();
9303
9304 Py_RETURN_NONE;
9305}
Larry Hastings2f936352014-08-05 14:04:04 +10009306#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009308
Larry Hastings2f936352014-08-05 14:04:04 +10009309/*[clinic input]
9310os.lseek -> Py_off_t
9311
9312 fd: int
9313 position: Py_off_t
9314 how: int
9315 /
9316
9317Set the position of a file descriptor. Return the new position.
9318
9319Return the new cursor position in number of bytes
9320relative to the beginning of the file.
9321[clinic start generated code]*/
9322
Larry Hastings2f936352014-08-05 14:04:04 +10009323static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009324os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
9325/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009326{
9327 Py_off_t result;
9328
Guido van Rossum687dd131993-05-17 08:34:16 +00009329#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00009330 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
9331 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10009332 case 0: how = SEEK_SET; break;
9333 case 1: how = SEEK_CUR; break;
9334 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009336#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009337
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009339 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02009340#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009341 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009342#else
Larry Hastings2f936352014-08-05 14:04:04 +10009343 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009344#endif
Steve Dower8fc89802015-04-12 00:26:27 -04009345 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009347 if (result < 0)
9348 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00009349
Larry Hastings2f936352014-08-05 14:04:04 +10009350 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00009351}
9352
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009353
Larry Hastings2f936352014-08-05 14:04:04 +10009354/*[clinic input]
9355os.read
9356 fd: int
9357 length: Py_ssize_t
9358 /
9359
9360Read from a file descriptor. Returns a bytes object.
9361[clinic start generated code]*/
9362
Larry Hastings2f936352014-08-05 14:04:04 +10009363static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009364os_read_impl(PyObject *module, int fd, Py_ssize_t length)
9365/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009366{
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 Py_ssize_t n;
9368 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10009369
9370 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 errno = EINVAL;
9372 return posix_error();
9373 }
Larry Hastings2f936352014-08-05 14:04:04 +10009374
Victor Stinner9a0d7a72018-11-22 15:03:40 +01009375 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10009376
9377 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 if (buffer == NULL)
9379 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009380
Victor Stinner66aab0c2015-03-19 22:53:20 +01009381 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
9382 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01009384 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 }
Larry Hastings2f936352014-08-05 14:04:04 +10009386
9387 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10009389
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00009391}
9392
Ross Lagerwall7807c352011-03-17 20:20:30 +02009393#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009394 || defined(__APPLE__))) \
9395 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9396 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9397static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009398iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009399{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009400 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009401
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009402 *iov = PyMem_New(struct iovec, cnt);
9403 if (*iov == NULL) {
9404 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009405 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009406 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009407
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009408 *buf = PyMem_New(Py_buffer, cnt);
9409 if (*buf == NULL) {
9410 PyMem_Del(*iov);
9411 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009412 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009413 }
9414
9415 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009416 PyObject *item = PySequence_GetItem(seq, i);
9417 if (item == NULL)
9418 goto fail;
9419 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9420 Py_DECREF(item);
9421 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009422 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009423 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009424 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009425 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009426 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009427 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009428
9429fail:
9430 PyMem_Del(*iov);
9431 for (j = 0; j < i; j++) {
9432 PyBuffer_Release(&(*buf)[j]);
9433 }
9434 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009435 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009436}
9437
9438static void
9439iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9440{
9441 int i;
9442 PyMem_Del(iov);
9443 for (i = 0; i < cnt; i++) {
9444 PyBuffer_Release(&buf[i]);
9445 }
9446 PyMem_Del(buf);
9447}
9448#endif
9449
Larry Hastings2f936352014-08-05 14:04:04 +10009450
Ross Lagerwall7807c352011-03-17 20:20:30 +02009451#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009452/*[clinic input]
9453os.readv -> Py_ssize_t
9454
9455 fd: int
9456 buffers: object
9457 /
9458
9459Read from a file descriptor fd into an iterable of buffers.
9460
9461The buffers should be mutable buffers accepting bytes.
9462readv will transfer data into each buffer until it is full
9463and then move on to the next buffer in the sequence to hold
9464the rest of the data.
9465
9466readv returns the total number of bytes read,
9467which may be less than the total capacity of all the buffers.
9468[clinic start generated code]*/
9469
Larry Hastings2f936352014-08-05 14:04:04 +10009470static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009471os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9472/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009473{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009474 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009475 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009476 struct iovec *iov;
9477 Py_buffer *buf;
9478
Larry Hastings2f936352014-08-05 14:04:04 +10009479 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009480 PyErr_SetString(PyExc_TypeError,
9481 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009482 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009483 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009484
Larry Hastings2f936352014-08-05 14:04:04 +10009485 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009486 if (cnt < 0)
9487 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009488
9489 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9490 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009491
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009492 do {
9493 Py_BEGIN_ALLOW_THREADS
9494 n = readv(fd, iov, cnt);
9495 Py_END_ALLOW_THREADS
9496 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009497
9498 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009499 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009500 if (!async_err)
9501 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009502 return -1;
9503 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009504
Larry Hastings2f936352014-08-05 14:04:04 +10009505 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009506}
Larry Hastings2f936352014-08-05 14:04:04 +10009507#endif /* HAVE_READV */
9508
Ross Lagerwall7807c352011-03-17 20:20:30 +02009509
9510#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009511/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009512os.pread
9513
9514 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009515 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009516 offset: Py_off_t
9517 /
9518
9519Read a number of bytes from a file descriptor starting at a particular offset.
9520
9521Read length bytes from file descriptor fd, starting at offset bytes from
9522the beginning of the file. The file offset remains unchanged.
9523[clinic start generated code]*/
9524
Larry Hastings2f936352014-08-05 14:04:04 +10009525static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009526os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9527/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009528{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009529 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009530 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009531 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009532
Larry Hastings2f936352014-08-05 14:04:04 +10009533 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009534 errno = EINVAL;
9535 return posix_error();
9536 }
Larry Hastings2f936352014-08-05 14:04:04 +10009537 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009538 if (buffer == NULL)
9539 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009540
9541 do {
9542 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009543 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009544 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009545 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009546 Py_END_ALLOW_THREADS
9547 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9548
Ross Lagerwall7807c352011-03-17 20:20:30 +02009549 if (n < 0) {
9550 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009551 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009552 }
Larry Hastings2f936352014-08-05 14:04:04 +10009553 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009554 _PyBytes_Resize(&buffer, n);
9555 return buffer;
9556}
Larry Hastings2f936352014-08-05 14:04:04 +10009557#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009558
Pablo Galindo4defba32018-01-27 16:16:37 +00009559#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9560/*[clinic input]
9561os.preadv -> Py_ssize_t
9562
9563 fd: int
9564 buffers: object
9565 offset: Py_off_t
9566 flags: int = 0
9567 /
9568
9569Reads from a file descriptor into a number of mutable bytes-like objects.
9570
9571Combines the functionality of readv() and pread(). As readv(), it will
9572transfer data into each buffer until it is full and then move on to the next
9573buffer in the sequence to hold the rest of the data. Its fourth argument,
9574specifies the file offset at which the input operation is to be performed. It
9575will return the total number of bytes read (which can be less than the total
9576capacity of all the objects).
9577
9578The flags argument contains a bitwise OR of zero or more of the following flags:
9579
9580- RWF_HIPRI
9581- RWF_NOWAIT
9582
9583Using non-zero flags requires Linux 4.6 or newer.
9584[clinic start generated code]*/
9585
9586static Py_ssize_t
9587os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9588 int flags)
9589/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9590{
9591 Py_ssize_t cnt, n;
9592 int async_err = 0;
9593 struct iovec *iov;
9594 Py_buffer *buf;
9595
9596 if (!PySequence_Check(buffers)) {
9597 PyErr_SetString(PyExc_TypeError,
9598 "preadv2() arg 2 must be a sequence");
9599 return -1;
9600 }
9601
9602 cnt = PySequence_Size(buffers);
9603 if (cnt < 0) {
9604 return -1;
9605 }
9606
9607#ifndef HAVE_PREADV2
9608 if(flags != 0) {
9609 argument_unavailable_error("preadv2", "flags");
9610 return -1;
9611 }
9612#endif
9613
9614 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9615 return -1;
9616 }
9617#ifdef HAVE_PREADV2
9618 do {
9619 Py_BEGIN_ALLOW_THREADS
9620 _Py_BEGIN_SUPPRESS_IPH
9621 n = preadv2(fd, iov, cnt, offset, flags);
9622 _Py_END_SUPPRESS_IPH
9623 Py_END_ALLOW_THREADS
9624 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9625#else
9626 do {
Ronald Oussoren41761932020-11-08 10:05:27 +01009627#ifdef __APPLE__
9628/* This entire function will be removed from the module dict when the API
9629 * is not available.
9630 */
9631#pragma clang diagnostic push
9632#pragma clang diagnostic ignored "-Wunguarded-availability"
9633#pragma clang diagnostic ignored "-Wunguarded-availability-new"
9634#endif
Pablo Galindo4defba32018-01-27 16:16:37 +00009635 Py_BEGIN_ALLOW_THREADS
9636 _Py_BEGIN_SUPPRESS_IPH
9637 n = preadv(fd, iov, cnt, offset);
9638 _Py_END_SUPPRESS_IPH
9639 Py_END_ALLOW_THREADS
9640 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +01009641
9642#ifdef __APPLE__
9643#pragma clang diagnostic pop
9644#endif
9645
Pablo Galindo4defba32018-01-27 16:16:37 +00009646#endif
9647
9648 iov_cleanup(iov, buf, cnt);
9649 if (n < 0) {
9650 if (!async_err) {
9651 posix_error();
9652 }
9653 return -1;
9654 }
9655
9656 return n;
9657}
9658#endif /* HAVE_PREADV */
9659
Larry Hastings2f936352014-08-05 14:04:04 +10009660
9661/*[clinic input]
9662os.write -> Py_ssize_t
9663
9664 fd: int
9665 data: Py_buffer
9666 /
9667
9668Write a bytes object to a file descriptor.
9669[clinic start generated code]*/
9670
Larry Hastings2f936352014-08-05 14:04:04 +10009671static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009672os_write_impl(PyObject *module, int fd, Py_buffer *data)
9673/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009674{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009675 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009676}
9677
9678#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009679#ifdef __APPLE__
9680/*[clinic input]
9681os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009682
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009683 out_fd: int
9684 in_fd: int
9685 offset: Py_off_t
9686 count as sbytes: Py_off_t
9687 headers: object(c_default="NULL") = ()
9688 trailers: object(c_default="NULL") = ()
9689 flags: int = 0
9690
9691Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9692[clinic start generated code]*/
9693
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009694static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009695os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9696 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9697 int flags)
9698/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9699#elif defined(__FreeBSD__) || defined(__DragonFly__)
9700/*[clinic input]
9701os.sendfile
9702
9703 out_fd: int
9704 in_fd: int
9705 offset: Py_off_t
9706 count: Py_ssize_t
9707 headers: object(c_default="NULL") = ()
9708 trailers: object(c_default="NULL") = ()
9709 flags: int = 0
9710
9711Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9712[clinic start generated code]*/
9713
9714static PyObject *
9715os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9716 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9717 int flags)
9718/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9719#else
9720/*[clinic input]
9721os.sendfile
9722
9723 out_fd: int
9724 in_fd: int
9725 offset as offobj: object
9726 count: Py_ssize_t
9727
9728Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9729[clinic start generated code]*/
9730
9731static PyObject *
9732os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9733 Py_ssize_t count)
9734/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9735#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009736{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009737 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009738 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009739
9740#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9741#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009742 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009743#endif
9744 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009745 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009746
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009747 sf.headers = NULL;
9748 sf.trailers = NULL;
9749
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009750 if (headers != NULL) {
9751 if (!PySequence_Check(headers)) {
9752 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009753 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009754 return NULL;
9755 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009756 Py_ssize_t i = PySequence_Size(headers);
9757 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009758 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009759 if (i > INT_MAX) {
9760 PyErr_SetString(PyExc_OverflowError,
9761 "sendfile() header is too large");
9762 return NULL;
9763 }
9764 if (i > 0) {
9765 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009766 if (iov_setup(&(sf.headers), &hbuf,
9767 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009768 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009769#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009770 for (i = 0; i < sf.hdr_cnt; i++) {
9771 Py_ssize_t blen = sf.headers[i].iov_len;
9772# define OFF_T_MAX 0x7fffffffffffffff
9773 if (sbytes >= OFF_T_MAX - blen) {
9774 PyErr_SetString(PyExc_OverflowError,
9775 "sendfile() header is too large");
9776 return NULL;
9777 }
9778 sbytes += blen;
9779 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009780#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009781 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009782 }
9783 }
9784 if (trailers != NULL) {
9785 if (!PySequence_Check(trailers)) {
9786 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009787 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009788 return NULL;
9789 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009790 Py_ssize_t i = PySequence_Size(trailers);
9791 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009792 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009793 if (i > INT_MAX) {
9794 PyErr_SetString(PyExc_OverflowError,
9795 "sendfile() trailer is too large");
9796 return NULL;
9797 }
9798 if (i > 0) {
9799 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009800 if (iov_setup(&(sf.trailers), &tbuf,
9801 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009802 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009803 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009804 }
9805 }
9806
Steve Dower8fc89802015-04-12 00:26:27 -04009807 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009808 do {
9809 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009810#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009811 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009812#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009813 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009814#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009815 Py_END_ALLOW_THREADS
9816 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009817 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009818
9819 if (sf.headers != NULL)
9820 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9821 if (sf.trailers != NULL)
9822 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9823
9824 if (ret < 0) {
9825 if ((errno == EAGAIN) || (errno == EBUSY)) {
9826 if (sbytes != 0) {
9827 // some data has been sent
9828 goto done;
9829 }
9830 else {
9831 // no data has been sent; upper application is supposed
9832 // to retry on EAGAIN or EBUSY
9833 return posix_error();
9834 }
9835 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009836 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009837 }
9838 goto done;
9839
9840done:
9841 #if !defined(HAVE_LARGEFILE_SUPPORT)
9842 return Py_BuildValue("l", sbytes);
9843 #else
9844 return Py_BuildValue("L", sbytes);
9845 #endif
9846
9847#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009848#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009849 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009850 do {
9851 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009852 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009853 Py_END_ALLOW_THREADS
9854 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009855 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009856 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009857 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009858 }
9859#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009860 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009861 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009862 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009863
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009864#if defined(__sun) && defined(__SVR4)
9865 // On Solaris, sendfile raises EINVAL rather than returning 0
9866 // when the offset is equal or bigger than the in_fd size.
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009867 struct stat st;
9868
9869 do {
9870 Py_BEGIN_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009871 ret = fstat(in_fd, &st);
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009872 Py_END_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009873 } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009874 if (ret < 0)
9875 return (!async_err) ? posix_error() : NULL;
9876
9877 if (offset >= st.st_size) {
9878 return Py_BuildValue("i", 0);
9879 }
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009880
9881 // On illumos specifically sendfile() may perform a partial write but
9882 // return -1/an error (in one confirmed case the destination socket
9883 // had a 5 second timeout set and errno was EAGAIN) and it's on the client
9884 // code to check if the offset parameter was modified by sendfile().
9885 //
9886 // We need this variable to track said change.
9887 off_t original_offset = offset;
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009888#endif
9889
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009890 do {
9891 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009892 ret = sendfile(out_fd, in_fd, &offset, count);
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009893#if defined(__sun) && defined(__SVR4)
9894 // This handles illumos-specific sendfile() partial write behavior,
9895 // see a comment above for more details.
9896 if (ret < 0 && offset != original_offset) {
9897 ret = offset - original_offset;
9898 }
9899#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009900 Py_END_ALLOW_THREADS
9901 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009902 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009903 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009904 return Py_BuildValue("n", ret);
9905#endif
9906}
Larry Hastings2f936352014-08-05 14:04:04 +10009907#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009908
Larry Hastings2f936352014-08-05 14:04:04 +10009909
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009910#if defined(__APPLE__)
9911/*[clinic input]
9912os._fcopyfile
9913
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009914 in_fd: int
9915 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009916 flags: int
9917 /
9918
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009919Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009920[clinic start generated code]*/
9921
9922static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009923os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9924/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009925{
9926 int ret;
9927
9928 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009929 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009930 Py_END_ALLOW_THREADS
9931 if (ret < 0)
9932 return posix_error();
9933 Py_RETURN_NONE;
9934}
9935#endif
9936
9937
Larry Hastings2f936352014-08-05 14:04:04 +10009938/*[clinic input]
9939os.fstat
9940
9941 fd : int
9942
9943Perform a stat system call on the given file descriptor.
9944
9945Like stat(), but for an open file descriptor.
9946Equivalent to os.stat(fd).
9947[clinic start generated code]*/
9948
Larry Hastings2f936352014-08-05 14:04:04 +10009949static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009950os_fstat_impl(PyObject *module, int fd)
9951/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009952{
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 STRUCT_STAT st;
9954 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009955 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009956
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009957 do {
9958 Py_BEGIN_ALLOW_THREADS
9959 res = FSTAT(fd, &st);
9960 Py_END_ALLOW_THREADS
9961 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009963#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009964 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009965#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009966 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009967#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 }
Tim Peters5aa91602002-01-30 05:46:57 +00009969
Victor Stinner1c2fa782020-05-10 11:05:29 +02009970 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009971}
9972
Larry Hastings2f936352014-08-05 14:04:04 +10009973
9974/*[clinic input]
9975os.isatty -> bool
9976 fd: int
9977 /
9978
9979Return True if the fd is connected to a terminal.
9980
9981Return True if the file descriptor is an open file descriptor
9982connected to the slave end of a terminal.
9983[clinic start generated code]*/
9984
Larry Hastings2f936352014-08-05 14:04:04 +10009985static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009986os_isatty_impl(PyObject *module, int fd)
9987/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009988{
Steve Dower8fc89802015-04-12 00:26:27 -04009989 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009990 _Py_BEGIN_SUPPRESS_IPH
9991 return_value = isatty(fd);
9992 _Py_END_SUPPRESS_IPH
9993 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009994}
9995
9996
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009997#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009998/*[clinic input]
9999os.pipe
10000
10001Create a pipe.
10002
10003Returns a tuple of two file descriptors:
10004 (read_fd, write_fd)
10005[clinic start generated code]*/
10006
Larry Hastings2f936352014-08-05 14:04:04 +100010007static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010008os_pipe_impl(PyObject *module)
10009/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +000010010{
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +020010012#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010014 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010016#else
10017 int res;
10018#endif
10019
10020#ifdef MS_WINDOWS
10021 attr.nLength = sizeof(attr);
10022 attr.lpSecurityDescriptor = NULL;
10023 attr.bInheritHandle = FALSE;
10024
10025 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -080010026 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +020010027 ok = CreatePipe(&read, &write, &attr, 0);
10028 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -070010029 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
10030 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010031 if (fds[0] == -1 || fds[1] == -1) {
10032 CloseHandle(read);
10033 CloseHandle(write);
10034 ok = 0;
10035 }
10036 }
Steve Dowerc3630612016-11-19 18:41:16 -080010037 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +020010038 Py_END_ALLOW_THREADS
10039
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +010010041 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010042#else
10043
10044#ifdef HAVE_PIPE2
10045 Py_BEGIN_ALLOW_THREADS
10046 res = pipe2(fds, O_CLOEXEC);
10047 Py_END_ALLOW_THREADS
10048
10049 if (res != 0 && errno == ENOSYS)
10050 {
10051#endif
10052 Py_BEGIN_ALLOW_THREADS
10053 res = pipe(fds);
10054 Py_END_ALLOW_THREADS
10055
10056 if (res == 0) {
10057 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
10058 close(fds[0]);
10059 close(fds[1]);
10060 return NULL;
10061 }
10062 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
10063 close(fds[0]);
10064 close(fds[1]);
10065 return NULL;
10066 }
10067 }
10068#ifdef HAVE_PIPE2
10069 }
10070#endif
10071
10072 if (res != 0)
10073 return PyErr_SetFromErrno(PyExc_OSError);
10074#endif /* !MS_WINDOWS */
10075 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +000010076}
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010077#endif /* HAVE_PIPE */
10078
Larry Hastings2f936352014-08-05 14:04:04 +100010079
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010080#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +100010081/*[clinic input]
10082os.pipe2
10083
10084 flags: int
10085 /
10086
10087Create a pipe with flags set atomically.
10088
10089Returns a tuple of two file descriptors:
10090 (read_fd, write_fd)
10091
10092flags can be constructed by ORing together one or more of these values:
10093O_NONBLOCK, O_CLOEXEC.
10094[clinic start generated code]*/
10095
Larry Hastings2f936352014-08-05 14:04:04 +100010096static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010097os_pipe2_impl(PyObject *module, int flags)
10098/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010099{
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010100 int fds[2];
10101 int res;
10102
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010103 res = pipe2(fds, flags);
10104 if (res != 0)
10105 return posix_error();
10106 return Py_BuildValue("(ii)", fds[0], fds[1]);
10107}
10108#endif /* HAVE_PIPE2 */
10109
Larry Hastings2f936352014-08-05 14:04:04 +100010110
Ross Lagerwall7807c352011-03-17 20:20:30 +020010111#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +100010112/*[clinic input]
10113os.writev -> Py_ssize_t
10114 fd: int
10115 buffers: object
10116 /
10117
10118Iterate over buffers, and write the contents of each to a file descriptor.
10119
10120Returns the total number of bytes written.
10121buffers must be a sequence of bytes-like objects.
10122[clinic start generated code]*/
10123
Larry Hastings2f936352014-08-05 14:04:04 +100010124static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010125os_writev_impl(PyObject *module, int fd, PyObject *buffers)
10126/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010127{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010128 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +100010129 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010130 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010131 struct iovec *iov;
10132 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +100010133
10134 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020010135 PyErr_SetString(PyExc_TypeError,
10136 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +100010137 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010138 }
Larry Hastings2f936352014-08-05 14:04:04 +100010139 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010140 if (cnt < 0)
10141 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010142
Larry Hastings2f936352014-08-05 14:04:04 +100010143 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10144 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010145 }
10146
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010147 do {
10148 Py_BEGIN_ALLOW_THREADS
10149 result = writev(fd, iov, cnt);
10150 Py_END_ALLOW_THREADS
10151 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +020010152
10153 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010154 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010155 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +010010156
Georg Brandl306336b2012-06-24 12:55:33 +020010157 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010158}
Larry Hastings2f936352014-08-05 14:04:04 +100010159#endif /* HAVE_WRITEV */
10160
10161
10162#ifdef HAVE_PWRITE
10163/*[clinic input]
10164os.pwrite -> Py_ssize_t
10165
10166 fd: int
10167 buffer: Py_buffer
10168 offset: Py_off_t
10169 /
10170
10171Write bytes to a file descriptor starting at a particular offset.
10172
10173Write buffer to fd, starting at offset bytes from the beginning of
10174the file. Returns the number of bytes writte. Does not change the
10175current file offset.
10176[clinic start generated code]*/
10177
Larry Hastings2f936352014-08-05 14:04:04 +100010178static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010179os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
10180/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010181{
10182 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010183 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010184
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010185 do {
10186 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -040010187 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010188 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -040010189 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010190 Py_END_ALLOW_THREADS
10191 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010192
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010193 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010194 posix_error();
10195 return size;
10196}
10197#endif /* HAVE_PWRITE */
10198
Pablo Galindo4defba32018-01-27 16:16:37 +000010199#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
10200/*[clinic input]
10201os.pwritev -> Py_ssize_t
10202
10203 fd: int
10204 buffers: object
10205 offset: Py_off_t
10206 flags: int = 0
10207 /
10208
10209Writes the contents of bytes-like objects to a file descriptor at a given offset.
10210
10211Combines the functionality of writev() and pwrite(). All buffers must be a sequence
10212of bytes-like objects. Buffers are processed in array order. Entire contents of first
10213buffer is written before proceeding to second, and so on. The operating system may
10214set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
10215This function writes the contents of each object to the file descriptor and returns
10216the total number of bytes written.
10217
10218The flags argument contains a bitwise OR of zero or more of the following flags:
10219
10220- RWF_DSYNC
10221- RWF_SYNC
YoSTEALTH76ef2552020-05-27 15:32:22 -060010222- RWF_APPEND
Pablo Galindo4defba32018-01-27 16:16:37 +000010223
10224Using non-zero flags requires Linux 4.7 or newer.
10225[clinic start generated code]*/
10226
10227static Py_ssize_t
10228os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
10229 int flags)
YoSTEALTH76ef2552020-05-27 15:32:22 -060010230/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/
Pablo Galindo4defba32018-01-27 16:16:37 +000010231{
10232 Py_ssize_t cnt;
10233 Py_ssize_t result;
10234 int async_err = 0;
10235 struct iovec *iov;
10236 Py_buffer *buf;
10237
10238 if (!PySequence_Check(buffers)) {
10239 PyErr_SetString(PyExc_TypeError,
10240 "pwritev() arg 2 must be a sequence");
10241 return -1;
10242 }
10243
10244 cnt = PySequence_Size(buffers);
10245 if (cnt < 0) {
10246 return -1;
10247 }
10248
10249#ifndef HAVE_PWRITEV2
10250 if(flags != 0) {
10251 argument_unavailable_error("pwritev2", "flags");
10252 return -1;
10253 }
10254#endif
10255
10256 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10257 return -1;
10258 }
10259#ifdef HAVE_PWRITEV2
10260 do {
10261 Py_BEGIN_ALLOW_THREADS
10262 _Py_BEGIN_SUPPRESS_IPH
10263 result = pwritev2(fd, iov, cnt, offset, flags);
10264 _Py_END_SUPPRESS_IPH
10265 Py_END_ALLOW_THREADS
10266 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10267#else
Ronald Oussoren41761932020-11-08 10:05:27 +010010268
10269#ifdef __APPLE__
10270/* This entire function will be removed from the module dict when the API
10271 * is not available.
10272 */
10273#pragma clang diagnostic push
10274#pragma clang diagnostic ignored "-Wunguarded-availability"
10275#pragma clang diagnostic ignored "-Wunguarded-availability-new"
10276#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000010277 do {
10278 Py_BEGIN_ALLOW_THREADS
10279 _Py_BEGIN_SUPPRESS_IPH
10280 result = pwritev(fd, iov, cnt, offset);
10281 _Py_END_SUPPRESS_IPH
10282 Py_END_ALLOW_THREADS
10283 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +010010284
10285#ifdef __APPLE__
10286#pragma clang diagnostic pop
10287#endif
10288
Pablo Galindo4defba32018-01-27 16:16:37 +000010289#endif
10290
10291 iov_cleanup(iov, buf, cnt);
10292 if (result < 0) {
10293 if (!async_err) {
10294 posix_error();
10295 }
10296 return -1;
10297 }
10298
10299 return result;
10300}
10301#endif /* HAVE_PWRITEV */
10302
Pablo Galindoaac4d032019-05-31 19:39:47 +010010303#ifdef HAVE_COPY_FILE_RANGE
10304/*[clinic input]
10305
10306os.copy_file_range
10307 src: int
10308 Source file descriptor.
10309 dst: int
10310 Destination file descriptor.
10311 count: Py_ssize_t
10312 Number of bytes to copy.
10313 offset_src: object = None
10314 Starting offset in src.
10315 offset_dst: object = None
10316 Starting offset in dst.
10317
10318Copy count bytes from one file descriptor to another.
10319
10320If offset_src is None, then src is read from the current position;
10321respectively for offset_dst.
10322[clinic start generated code]*/
10323
10324static PyObject *
10325os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10326 PyObject *offset_src, PyObject *offset_dst)
10327/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
10328{
10329 off_t offset_src_val, offset_dst_val;
10330 off_t *p_offset_src = NULL;
10331 off_t *p_offset_dst = NULL;
10332 Py_ssize_t ret;
10333 int async_err = 0;
10334 /* The flags argument is provided to allow
10335 * for future extensions and currently must be to 0. */
10336 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +000010337
10338
Pablo Galindoaac4d032019-05-31 19:39:47 +010010339 if (count < 0) {
10340 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10341 return NULL;
10342 }
10343
10344 if (offset_src != Py_None) {
10345 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10346 return NULL;
10347 }
10348 p_offset_src = &offset_src_val;
10349 }
10350
10351 if (offset_dst != Py_None) {
10352 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10353 return NULL;
10354 }
10355 p_offset_dst = &offset_dst_val;
10356 }
10357
10358 do {
10359 Py_BEGIN_ALLOW_THREADS
10360 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
10361 Py_END_ALLOW_THREADS
10362 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10363
10364 if (ret < 0) {
10365 return (!async_err) ? posix_error() : NULL;
10366 }
10367
10368 return PyLong_FromSsize_t(ret);
10369}
10370#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +100010371
Pablo Galindoa57b3d32020-11-17 00:00:38 +000010372#ifdef HAVE_SPLICE
10373/*[clinic input]
10374
10375os.splice
10376 src: int
10377 Source file descriptor.
10378 dst: int
10379 Destination file descriptor.
10380 count: Py_ssize_t
10381 Number of bytes to copy.
10382 offset_src: object = None
10383 Starting offset in src.
10384 offset_dst: object = None
10385 Starting offset in dst.
10386 flags: unsigned_int = 0
10387 Flags to modify the semantics of the call.
10388
10389Transfer count bytes from one pipe to a descriptor or vice versa.
10390
10391If offset_src is None, then src is read from the current position;
10392respectively for offset_dst. The offset associated to the file
10393descriptor that refers to a pipe must be None.
10394[clinic start generated code]*/
10395
10396static PyObject *
10397os_splice_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10398 PyObject *offset_src, PyObject *offset_dst,
10399 unsigned int flags)
10400/*[clinic end generated code: output=d0386f25a8519dc5 input=047527c66c6d2e0a]*/
10401{
10402 off_t offset_src_val, offset_dst_val;
10403 off_t *p_offset_src = NULL;
10404 off_t *p_offset_dst = NULL;
10405 Py_ssize_t ret;
10406 int async_err = 0;
10407
10408 if (count < 0) {
10409 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10410 return NULL;
10411 }
10412
10413 if (offset_src != Py_None) {
10414 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10415 return NULL;
10416 }
10417 p_offset_src = &offset_src_val;
10418 }
10419
10420 if (offset_dst != Py_None) {
10421 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10422 return NULL;
10423 }
10424 p_offset_dst = &offset_dst_val;
10425 }
10426
10427 do {
10428 Py_BEGIN_ALLOW_THREADS
10429 ret = splice(src, p_offset_src, dst, p_offset_dst, count, flags);
10430 Py_END_ALLOW_THREADS
10431 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10432
10433 if (ret < 0) {
10434 return (!async_err) ? posix_error() : NULL;
10435 }
10436
10437 return PyLong_FromSsize_t(ret);
10438}
10439#endif /* HAVE_SPLICE*/
10440
Larry Hastings2f936352014-08-05 14:04:04 +100010441#ifdef HAVE_MKFIFO
10442/*[clinic input]
10443os.mkfifo
10444
10445 path: path_t
10446 mode: int=0o666
10447 *
10448 dir_fd: dir_fd(requires='mkfifoat')=None
10449
10450Create a "fifo" (a POSIX named pipe).
10451
10452If dir_fd is not None, it should be a file descriptor open to a directory,
10453 and path should be relative; path will then be relative to that directory.
10454dir_fd may not be implemented on your platform.
10455 If it is unavailable, using it will raise a NotImplementedError.
10456[clinic start generated code]*/
10457
Larry Hastings2f936352014-08-05 14:04:04 +100010458static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010459os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
10460/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010461{
10462 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010463 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010464
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010465 do {
10466 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010467#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010468 if (dir_fd != DEFAULT_DIR_FD)
10469 result = mkfifoat(dir_fd, path->narrow, mode);
10470 else
Ross Lagerwall7807c352011-03-17 20:20:30 +020010471#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010472 result = mkfifo(path->narrow, mode);
10473 Py_END_ALLOW_THREADS
10474 } while (result != 0 && errno == EINTR &&
10475 !(async_err = PyErr_CheckSignals()));
10476 if (result != 0)
10477 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010478
10479 Py_RETURN_NONE;
10480}
10481#endif /* HAVE_MKFIFO */
10482
10483
10484#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
10485/*[clinic input]
10486os.mknod
10487
10488 path: path_t
10489 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010490 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +100010491 *
10492 dir_fd: dir_fd(requires='mknodat')=None
10493
10494Create a node in the file system.
10495
10496Create a node in the file system (file, device special file or named pipe)
10497at path. mode specifies both the permissions to use and the
10498type of node to be created, being combined (bitwise OR) with one of
10499S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
10500device defines the newly created device special file (probably using
10501os.makedev()). Otherwise device is ignored.
10502
10503If dir_fd is not None, it should be a file descriptor open to a directory,
10504 and path should be relative; path will then be relative to that directory.
10505dir_fd may not be implemented on your platform.
10506 If it is unavailable, using it will raise a NotImplementedError.
10507[clinic start generated code]*/
10508
Larry Hastings2f936352014-08-05 14:04:04 +100010509static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010510os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -040010511 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010512/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010513{
10514 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010515 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010516
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010517 do {
10518 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010519#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010520 if (dir_fd != DEFAULT_DIR_FD)
10521 result = mknodat(dir_fd, path->narrow, mode, device);
10522 else
Larry Hastings2f936352014-08-05 14:04:04 +100010523#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010524 result = mknod(path->narrow, mode, device);
10525 Py_END_ALLOW_THREADS
10526 } while (result != 0 && errno == EINTR &&
10527 !(async_err = PyErr_CheckSignals()));
10528 if (result != 0)
10529 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010530
10531 Py_RETURN_NONE;
10532}
10533#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10534
10535
10536#ifdef HAVE_DEVICE_MACROS
10537/*[clinic input]
10538os.major -> unsigned_int
10539
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010540 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010541 /
10542
10543Extracts a device major number from a raw device number.
10544[clinic start generated code]*/
10545
Larry Hastings2f936352014-08-05 14:04:04 +100010546static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010547os_major_impl(PyObject *module, dev_t device)
10548/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010549{
10550 return major(device);
10551}
10552
10553
10554/*[clinic input]
10555os.minor -> unsigned_int
10556
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010557 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010558 /
10559
10560Extracts a device minor number from a raw device number.
10561[clinic start generated code]*/
10562
Larry Hastings2f936352014-08-05 14:04:04 +100010563static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010564os_minor_impl(PyObject *module, dev_t device)
10565/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010566{
10567 return minor(device);
10568}
10569
10570
10571/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010572os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010573
10574 major: int
10575 minor: int
10576 /
10577
10578Composes a raw device number from the major and minor device numbers.
10579[clinic start generated code]*/
10580
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010581static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010582os_makedev_impl(PyObject *module, int major, int minor)
10583/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010584{
10585 return makedev(major, minor);
10586}
10587#endif /* HAVE_DEVICE_MACROS */
10588
10589
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010590#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010591/*[clinic input]
10592os.ftruncate
10593
10594 fd: int
10595 length: Py_off_t
10596 /
10597
10598Truncate a file, specified by file descriptor, to a specific length.
10599[clinic start generated code]*/
10600
Larry Hastings2f936352014-08-05 14:04:04 +100010601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010602os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10603/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010604{
10605 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010606 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010607
Steve Dowerb82e17e2019-05-23 08:45:22 -070010608 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10609 return NULL;
10610 }
10611
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010612 do {
10613 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010614 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010615#ifdef MS_WINDOWS
10616 result = _chsize_s(fd, length);
10617#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010618 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010619#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010620 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010621 Py_END_ALLOW_THREADS
10622 } while (result != 0 && errno == EINTR &&
10623 !(async_err = PyErr_CheckSignals()));
10624 if (result != 0)
10625 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010626 Py_RETURN_NONE;
10627}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010628#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010629
10630
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010631#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010632/*[clinic input]
10633os.truncate
10634 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10635 length: Py_off_t
10636
10637Truncate a file, specified by path, to a specific length.
10638
10639On some platforms, path may also be specified as an open file descriptor.
10640 If this functionality is unavailable, using it raises an exception.
10641[clinic start generated code]*/
10642
Larry Hastings2f936352014-08-05 14:04:04 +100010643static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010644os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10645/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010646{
10647 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010648#ifdef MS_WINDOWS
10649 int fd;
10650#endif
10651
10652 if (path->fd != -1)
10653 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010654
Steve Dowerb82e17e2019-05-23 08:45:22 -070010655 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10656 return NULL;
10657 }
10658
Larry Hastings2f936352014-08-05 14:04:04 +100010659 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010660 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010661#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010662 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010663 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010664 result = -1;
10665 else {
10666 result = _chsize_s(fd, length);
10667 close(fd);
10668 if (result < 0)
10669 errno = result;
10670 }
10671#else
10672 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010673#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010674 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010675 Py_END_ALLOW_THREADS
10676 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010677 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010678
10679 Py_RETURN_NONE;
10680}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010681#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010682
Ross Lagerwall7807c352011-03-17 20:20:30 +020010683
Victor Stinnerd6b17692014-09-30 12:20:05 +020010684/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10685 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10686 defined, which is the case in Python on AIX. AIX bug report:
10687 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10688#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10689# define POSIX_FADVISE_AIX_BUG
10690#endif
10691
Victor Stinnerec39e262014-09-30 12:35:58 +020010692
Victor Stinnerd6b17692014-09-30 12:20:05 +020010693#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010694/*[clinic input]
10695os.posix_fallocate
10696
10697 fd: int
10698 offset: Py_off_t
10699 length: Py_off_t
10700 /
10701
10702Ensure a file has allocated at least a particular number of bytes on disk.
10703
10704Ensure that the file specified by fd encompasses a range of bytes
10705starting at offset bytes from the beginning and continuing for length bytes.
10706[clinic start generated code]*/
10707
Larry Hastings2f936352014-08-05 14:04:04 +100010708static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010709os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010710 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010711/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010712{
10713 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010714 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010715
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010716 do {
10717 Py_BEGIN_ALLOW_THREADS
10718 result = posix_fallocate(fd, offset, length);
10719 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010720 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10721
10722 if (result == 0)
10723 Py_RETURN_NONE;
10724
10725 if (async_err)
10726 return NULL;
10727
10728 errno = result;
10729 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010730}
Victor Stinnerec39e262014-09-30 12:35:58 +020010731#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010732
Ross Lagerwall7807c352011-03-17 20:20:30 +020010733
Victor Stinnerd6b17692014-09-30 12:20:05 +020010734#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010735/*[clinic input]
10736os.posix_fadvise
10737
10738 fd: int
10739 offset: Py_off_t
10740 length: Py_off_t
10741 advice: int
10742 /
10743
10744Announce an intention to access data in a specific pattern.
10745
10746Announce an intention to access data in a specific pattern, thus allowing
10747the kernel to make optimizations.
10748The advice applies to the region of the file specified by fd starting at
10749offset and continuing for length bytes.
10750advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10751POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10752POSIX_FADV_DONTNEED.
10753[clinic start generated code]*/
10754
Larry Hastings2f936352014-08-05 14:04:04 +100010755static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010756os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010757 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010758/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010759{
10760 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010761 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010762
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010763 do {
10764 Py_BEGIN_ALLOW_THREADS
10765 result = posix_fadvise(fd, offset, length, advice);
10766 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010767 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10768
10769 if (result == 0)
10770 Py_RETURN_NONE;
10771
10772 if (async_err)
10773 return NULL;
10774
10775 errno = result;
10776 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010777}
Victor Stinnerec39e262014-09-30 12:35:58 +020010778#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010780
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010781#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010782static PyObject*
10783win32_putenv(PyObject *name, PyObject *value)
10784{
10785 /* Search from index 1 because on Windows starting '=' is allowed for
10786 defining hidden environment variables. */
10787 if (PyUnicode_GET_LENGTH(name) == 0 ||
10788 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10789 {
10790 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10791 return NULL;
10792 }
10793 PyObject *unicode;
10794 if (value != NULL) {
10795 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10796 }
10797 else {
10798 unicode = PyUnicode_FromFormat("%U=", name);
10799 }
10800 if (unicode == NULL) {
10801 return NULL;
10802 }
10803
10804 Py_ssize_t size;
10805 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10806 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10807 Py_DECREF(unicode);
10808
10809 if (env == NULL) {
10810 return NULL;
10811 }
10812 if (size > _MAX_ENV) {
10813 PyErr_Format(PyExc_ValueError,
10814 "the environment variable is longer than %u characters",
10815 _MAX_ENV);
10816 PyMem_Free(env);
10817 return NULL;
10818 }
10819
10820 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10821 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10822 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10823
10824 Prefer _wputenv() to be compatible with C libraries using CRT
10825 variables and CRT functions using these variables (ex: getenv()). */
10826 int err = _wputenv(env);
10827 PyMem_Free(env);
10828
10829 if (err) {
10830 posix_error();
10831 return NULL;
10832 }
10833
10834 Py_RETURN_NONE;
10835}
10836#endif
10837
10838
10839#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010840/*[clinic input]
10841os.putenv
10842
10843 name: unicode
10844 value: unicode
10845 /
10846
10847Change or add an environment variable.
10848[clinic start generated code]*/
10849
Larry Hastings2f936352014-08-05 14:04:04 +100010850static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010851os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10852/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010853{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010854 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10855 return NULL;
10856 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010857 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010858}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010859#else
Larry Hastings2f936352014-08-05 14:04:04 +100010860/*[clinic input]
10861os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010862
Larry Hastings2f936352014-08-05 14:04:04 +100010863 name: FSConverter
10864 value: FSConverter
10865 /
10866
10867Change or add an environment variable.
10868[clinic start generated code]*/
10869
Larry Hastings2f936352014-08-05 14:04:04 +100010870static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010871os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10872/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010873{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010874 const char *name_string = PyBytes_AS_STRING(name);
10875 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010876
Serhiy Storchaka77703942017-06-25 07:33:01 +030010877 if (strchr(name_string, '=') != NULL) {
10878 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10879 return NULL;
10880 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010881
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010882 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10883 return NULL;
10884 }
10885
Victor Stinnerb477d192020-01-22 22:48:16 +010010886 if (setenv(name_string, value_string, 1)) {
10887 return posix_error();
10888 }
Larry Hastings2f936352014-08-05 14:04:04 +100010889 Py_RETURN_NONE;
10890}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010891#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010892
10893
Victor Stinner161e7b32020-01-24 11:53:44 +010010894#ifdef MS_WINDOWS
10895/*[clinic input]
10896os.unsetenv
10897 name: unicode
10898 /
10899
10900Delete an environment variable.
10901[clinic start generated code]*/
10902
10903static PyObject *
10904os_unsetenv_impl(PyObject *module, PyObject *name)
10905/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10906{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010907 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10908 return NULL;
10909 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010910 return win32_putenv(name, NULL);
10911}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010912#else
Larry Hastings2f936352014-08-05 14:04:04 +100010913/*[clinic input]
10914os.unsetenv
10915 name: FSConverter
10916 /
10917
10918Delete an environment variable.
10919[clinic start generated code]*/
10920
Larry Hastings2f936352014-08-05 14:04:04 +100010921static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010922os_unsetenv_impl(PyObject *module, PyObject *name)
10923/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010924{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010925 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10926 return NULL;
10927 }
Victor Stinner984890f2011-11-24 13:53:38 +010010928#ifdef HAVE_BROKEN_UNSETENV
10929 unsetenv(PyBytes_AS_STRING(name));
10930#else
Victor Stinner161e7b32020-01-24 11:53:44 +010010931 int err = unsetenv(PyBytes_AS_STRING(name));
10932 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010010933 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010010934 }
Victor Stinner984890f2011-11-24 13:53:38 +010010935#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010936
Victor Stinner84ae1182010-05-06 22:05:07 +000010937 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010938}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010939#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000010940
Larry Hastings2f936352014-08-05 14:04:04 +100010941
10942/*[clinic input]
10943os.strerror
10944
10945 code: int
10946 /
10947
10948Translate an error code to a message string.
10949[clinic start generated code]*/
10950
Larry Hastings2f936352014-08-05 14:04:04 +100010951static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010952os_strerror_impl(PyObject *module, int code)
10953/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010954{
10955 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 if (message == NULL) {
10957 PyErr_SetString(PyExc_ValueError,
10958 "strerror() argument out of range");
10959 return NULL;
10960 }
Victor Stinner1b579672011-12-17 05:47:23 +010010961 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010962}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010963
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010964
Guido van Rossumc9641791998-08-04 15:26:23 +000010965#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010966#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010967/*[clinic input]
10968os.WCOREDUMP -> bool
10969
10970 status: int
10971 /
10972
10973Return True if the process returning status was dumped to a core file.
10974[clinic start generated code]*/
10975
Larry Hastings2f936352014-08-05 14:04:04 +100010976static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010977os_WCOREDUMP_impl(PyObject *module, int status)
10978/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010979{
10980 WAIT_TYPE wait_status;
10981 WAIT_STATUS_INT(wait_status) = status;
10982 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010983}
10984#endif /* WCOREDUMP */
10985
Larry Hastings2f936352014-08-05 14:04:04 +100010986
Fred Drake106c1a02002-04-23 15:58:02 +000010987#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010988/*[clinic input]
10989os.WIFCONTINUED -> bool
10990
10991 status: int
10992
10993Return True if a particular process was continued from a job control stop.
10994
10995Return True if the process returning status was continued from a
10996job control stop.
10997[clinic start generated code]*/
10998
Larry Hastings2f936352014-08-05 14:04:04 +100010999static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011000os_WIFCONTINUED_impl(PyObject *module, int status)
11001/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011002{
11003 WAIT_TYPE wait_status;
11004 WAIT_STATUS_INT(wait_status) = status;
11005 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000011006}
11007#endif /* WIFCONTINUED */
11008
Larry Hastings2f936352014-08-05 14:04:04 +100011009
Guido van Rossumc9641791998-08-04 15:26:23 +000011010#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100011011/*[clinic input]
11012os.WIFSTOPPED -> bool
11013
11014 status: int
11015
11016Return True if the process returning status was stopped.
11017[clinic start generated code]*/
11018
Larry Hastings2f936352014-08-05 14:04:04 +100011019static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011020os_WIFSTOPPED_impl(PyObject *module, int status)
11021/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011022{
11023 WAIT_TYPE wait_status;
11024 WAIT_STATUS_INT(wait_status) = status;
11025 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011026}
11027#endif /* WIFSTOPPED */
11028
Larry Hastings2f936352014-08-05 14:04:04 +100011029
Guido van Rossumc9641791998-08-04 15:26:23 +000011030#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100011031/*[clinic input]
11032os.WIFSIGNALED -> bool
11033
11034 status: int
11035
11036Return True if the process returning status was terminated by a signal.
11037[clinic start generated code]*/
11038
Larry Hastings2f936352014-08-05 14:04:04 +100011039static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011040os_WIFSIGNALED_impl(PyObject *module, int status)
11041/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011042{
11043 WAIT_TYPE wait_status;
11044 WAIT_STATUS_INT(wait_status) = status;
11045 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011046}
11047#endif /* WIFSIGNALED */
11048
Larry Hastings2f936352014-08-05 14:04:04 +100011049
Guido van Rossumc9641791998-08-04 15:26:23 +000011050#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100011051/*[clinic input]
11052os.WIFEXITED -> bool
11053
11054 status: int
11055
11056Return True if the process returning status exited via the exit() system call.
11057[clinic start generated code]*/
11058
Larry Hastings2f936352014-08-05 14:04:04 +100011059static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011060os_WIFEXITED_impl(PyObject *module, int status)
11061/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011062{
11063 WAIT_TYPE wait_status;
11064 WAIT_STATUS_INT(wait_status) = status;
11065 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011066}
11067#endif /* WIFEXITED */
11068
Larry Hastings2f936352014-08-05 14:04:04 +100011069
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000011070#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100011071/*[clinic input]
11072os.WEXITSTATUS -> int
11073
11074 status: int
11075
11076Return the process return code from status.
11077[clinic start generated code]*/
11078
Larry Hastings2f936352014-08-05 14:04:04 +100011079static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011080os_WEXITSTATUS_impl(PyObject *module, int status)
11081/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011082{
11083 WAIT_TYPE wait_status;
11084 WAIT_STATUS_INT(wait_status) = status;
11085 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011086}
11087#endif /* WEXITSTATUS */
11088
Larry Hastings2f936352014-08-05 14:04:04 +100011089
Guido van Rossumc9641791998-08-04 15:26:23 +000011090#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011091/*[clinic input]
11092os.WTERMSIG -> int
11093
11094 status: int
11095
11096Return the signal that terminated the process that provided the status value.
11097[clinic start generated code]*/
11098
Larry Hastings2f936352014-08-05 14:04:04 +100011099static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011100os_WTERMSIG_impl(PyObject *module, int status)
11101/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011102{
11103 WAIT_TYPE wait_status;
11104 WAIT_STATUS_INT(wait_status) = status;
11105 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011106}
11107#endif /* WTERMSIG */
11108
Larry Hastings2f936352014-08-05 14:04:04 +100011109
Guido van Rossumc9641791998-08-04 15:26:23 +000011110#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011111/*[clinic input]
11112os.WSTOPSIG -> int
11113
11114 status: int
11115
11116Return the signal that stopped the process that provided the status value.
11117[clinic start generated code]*/
11118
Larry Hastings2f936352014-08-05 14:04:04 +100011119static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011120os_WSTOPSIG_impl(PyObject *module, int status)
11121/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011122{
11123 WAIT_TYPE wait_status;
11124 WAIT_STATUS_INT(wait_status) = status;
11125 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011126}
11127#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000011128#endif /* HAVE_SYS_WAIT_H */
11129
11130
Thomas Wouters477c8d52006-05-27 19:21:47 +000011131#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000011132#ifdef _SCO_DS
11133/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
11134 needed definitions in sys/statvfs.h */
11135#define _SVID3
11136#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011137#include <sys/statvfs.h>
11138
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011139static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020011140_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
11141 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080011142 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 if (v == NULL)
11144 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011145
11146#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011147 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11148 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11149 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
11150 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
11151 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
11152 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
11153 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
11154 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
11155 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11156 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011157#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011158 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11159 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11160 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011161 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000011162 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011163 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011165 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011167 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000011168 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011169 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011171 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11173 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011174#endif
Michael Felt502d5512018-01-05 13:01:58 +010011175/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
11176 * (issue #32390). */
11177#if defined(_AIX) && defined(_ALL_SOURCE)
11178 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
11179#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010011180 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010011181#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010011182 if (PyErr_Occurred()) {
11183 Py_DECREF(v);
11184 return NULL;
11185 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011186
Victor Stinner8c62be82010-05-06 00:08:46 +000011187 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011188}
11189
Larry Hastings2f936352014-08-05 14:04:04 +100011190
11191/*[clinic input]
11192os.fstatvfs
11193 fd: int
11194 /
11195
11196Perform an fstatvfs system call on the given fd.
11197
11198Equivalent to statvfs(fd).
11199[clinic start generated code]*/
11200
Larry Hastings2f936352014-08-05 14:04:04 +100011201static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011202os_fstatvfs_impl(PyObject *module, int fd)
11203/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011204{
11205 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011206 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011207 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011208
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011209 do {
11210 Py_BEGIN_ALLOW_THREADS
11211 result = fstatvfs(fd, &st);
11212 Py_END_ALLOW_THREADS
11213 } while (result != 0 && errno == EINTR &&
11214 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100011215 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011216 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011217
Victor Stinner1c2fa782020-05-10 11:05:29 +020011218 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011219}
Larry Hastings2f936352014-08-05 14:04:04 +100011220#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000011221
11222
Thomas Wouters477c8d52006-05-27 19:21:47 +000011223#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000011224#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100011225/*[clinic input]
11226os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000011227
Larry Hastings2f936352014-08-05 14:04:04 +100011228 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
11229
11230Perform a statvfs system call on the given path.
11231
11232path may always be specified as a string.
11233On some platforms, path may also be specified as an open file descriptor.
11234 If this functionality is unavailable, using it raises an exception.
11235[clinic start generated code]*/
11236
Larry Hastings2f936352014-08-05 14:04:04 +100011237static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011238os_statvfs_impl(PyObject *module, path_t *path)
11239/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011240{
11241 int result;
11242 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011243
11244 Py_BEGIN_ALLOW_THREADS
11245#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100011246 if (path->fd != -1) {
Larry Hastings2f936352014-08-05 14:04:04 +100011247 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011248 }
11249 else
11250#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011251 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011252 Py_END_ALLOW_THREADS
11253
11254 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011255 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011256 }
11257
Victor Stinner1c2fa782020-05-10 11:05:29 +020011258 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011259}
Larry Hastings2f936352014-08-05 14:04:04 +100011260#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
11261
Guido van Rossum94f6f721999-01-06 18:42:14 +000011262
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011263#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011264/*[clinic input]
11265os._getdiskusage
11266
Steve Dower23ad6d02018-02-22 10:39:10 -080011267 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100011268
11269Return disk usage statistics about the given path as a (total, free) tuple.
11270[clinic start generated code]*/
11271
Larry Hastings2f936352014-08-05 14:04:04 +100011272static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080011273os__getdiskusage_impl(PyObject *module, path_t *path)
11274/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011275{
11276 BOOL retval;
11277 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040011278 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011279
11280 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080011281 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011282 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040011283 if (retval == 0) {
11284 if (GetLastError() == ERROR_DIRECTORY) {
11285 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011286
Joe Pamerc8c02492018-09-25 10:57:36 -040011287 dir_path = PyMem_New(wchar_t, path->length + 1);
11288 if (dir_path == NULL) {
11289 return PyErr_NoMemory();
11290 }
11291
11292 wcscpy_s(dir_path, path->length + 1, path->wide);
11293
11294 if (_dirnameW(dir_path) != -1) {
11295 Py_BEGIN_ALLOW_THREADS
11296 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
11297 Py_END_ALLOW_THREADS
11298 }
11299 /* Record the last error in case it's modified by PyMem_Free. */
11300 err = GetLastError();
11301 PyMem_Free(dir_path);
11302 if (retval) {
11303 goto success;
11304 }
11305 }
11306 return PyErr_SetFromWindowsErr(err);
11307 }
11308
11309success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011310 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
11311}
Larry Hastings2f936352014-08-05 14:04:04 +100011312#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011313
11314
Fred Drakec9680921999-12-13 16:37:25 +000011315/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
11316 * It maps strings representing configuration variable names to
11317 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000011318 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000011319 * rarely-used constants. There are three separate tables that use
11320 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000011321 *
11322 * This code is always included, even if none of the interfaces that
11323 * need it are included. The #if hackery needed to avoid it would be
11324 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000011325 */
11326struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011327 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011328 int value;
Fred Drakec9680921999-12-13 16:37:25 +000011329};
11330
Fred Drake12c6e2d1999-12-14 21:25:03 +000011331static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011332conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000011333 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000011334{
Christian Heimes217cfd12007-12-02 14:31:20 +000011335 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011336 int value = _PyLong_AsInt(arg);
11337 if (value == -1 && PyErr_Occurred())
11338 return 0;
11339 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000011340 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000011341 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000011342 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000011343 /* look up the value in the table using a binary search */
11344 size_t lo = 0;
11345 size_t mid;
11346 size_t hi = tablesize;
11347 int cmp;
11348 const char *confname;
11349 if (!PyUnicode_Check(arg)) {
11350 PyErr_SetString(PyExc_TypeError,
11351 "configuration names must be strings or integers");
11352 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020011354 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000011355 if (confname == NULL)
11356 return 0;
11357 while (lo < hi) {
11358 mid = (lo + hi) / 2;
11359 cmp = strcmp(confname, table[mid].name);
11360 if (cmp < 0)
11361 hi = mid;
11362 else if (cmp > 0)
11363 lo = mid + 1;
11364 else {
11365 *valuep = table[mid].value;
11366 return 1;
11367 }
11368 }
11369 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
11370 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011371 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000011372}
11373
11374
11375#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
11376static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011377#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011379#endif
11380#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011382#endif
Fred Drakec9680921999-12-13 16:37:25 +000011383#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011385#endif
11386#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000011388#endif
11389#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000011391#endif
11392#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000011394#endif
11395#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011397#endif
11398#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000011399 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000011400#endif
11401#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000011403#endif
11404#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011406#endif
11407#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011408 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000011409#endif
11410#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011412#endif
11413#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000011415#endif
11416#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011418#endif
11419#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011420 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000011421#endif
11422#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011424#endif
11425#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000011427#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000011428#ifdef _PC_ACL_ENABLED
11429 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
11430#endif
11431#ifdef _PC_MIN_HOLE_SIZE
11432 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
11433#endif
11434#ifdef _PC_ALLOC_SIZE_MIN
11435 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
11436#endif
11437#ifdef _PC_REC_INCR_XFER_SIZE
11438 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
11439#endif
11440#ifdef _PC_REC_MAX_XFER_SIZE
11441 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
11442#endif
11443#ifdef _PC_REC_MIN_XFER_SIZE
11444 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
11445#endif
11446#ifdef _PC_REC_XFER_ALIGN
11447 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
11448#endif
11449#ifdef _PC_SYMLINK_MAX
11450 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
11451#endif
11452#ifdef _PC_XATTR_ENABLED
11453 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
11454#endif
11455#ifdef _PC_XATTR_EXISTS
11456 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
11457#endif
11458#ifdef _PC_TIMESTAMP_RESOLUTION
11459 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
11460#endif
Fred Drakec9680921999-12-13 16:37:25 +000011461};
11462
Fred Drakec9680921999-12-13 16:37:25 +000011463static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011464conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011465{
11466 return conv_confname(arg, valuep, posix_constants_pathconf,
11467 sizeof(posix_constants_pathconf)
11468 / sizeof(struct constdef));
11469}
11470#endif
11471
Larry Hastings2f936352014-08-05 14:04:04 +100011472
Fred Drakec9680921999-12-13 16:37:25 +000011473#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011474/*[clinic input]
11475os.fpathconf -> long
11476
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011477 fd: fildes
Larry Hastings2f936352014-08-05 14:04:04 +100011478 name: path_confname
11479 /
11480
11481Return the configuration limit name for the file descriptor fd.
11482
11483If there is no limit, return -1.
11484[clinic start generated code]*/
11485
Larry Hastings2f936352014-08-05 14:04:04 +100011486static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011487os_fpathconf_impl(PyObject *module, int fd, int name)
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011488/*[clinic end generated code: output=d5b7042425fc3e21 input=5b8d2471cfaae186]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011489{
11490 long limit;
11491
11492 errno = 0;
11493 limit = fpathconf(fd, name);
11494 if (limit == -1 && errno != 0)
11495 posix_error();
11496
11497 return limit;
11498}
11499#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011500
11501
11502#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011503/*[clinic input]
11504os.pathconf -> long
11505 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
11506 name: path_confname
11507
11508Return the configuration limit name for the file or directory path.
11509
11510If there is no limit, return -1.
11511On some platforms, path may also be specified as an open file descriptor.
11512 If this functionality is unavailable, using it raises an exception.
11513[clinic start generated code]*/
11514
Larry Hastings2f936352014-08-05 14:04:04 +100011515static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011516os_pathconf_impl(PyObject *module, path_t *path, int name)
11517/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011518{
Victor Stinner8c62be82010-05-06 00:08:46 +000011519 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000011520
Victor Stinner8c62be82010-05-06 00:08:46 +000011521 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020011522#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011523 if (path->fd != -1)
11524 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011525 else
11526#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011527 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 if (limit == -1 && errno != 0) {
11529 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011530 /* could be a path or name problem */
11531 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011532 else
Larry Hastings2f936352014-08-05 14:04:04 +100011533 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 }
Larry Hastings2f936352014-08-05 14:04:04 +100011535
11536 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011537}
Larry Hastings2f936352014-08-05 14:04:04 +100011538#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011539
11540#ifdef HAVE_CONFSTR
11541static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011542#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011544#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011545#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011547#endif
11548#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011550#endif
Fred Draked86ed291999-12-15 15:34:33 +000011551#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011553#endif
11554#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011556#endif
11557#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011559#endif
11560#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011562#endif
Fred Drakec9680921999-12-13 16:37:25 +000011563#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011564 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011565#endif
11566#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011567 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011568#endif
11569#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011570 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011571#endif
11572#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011574#endif
11575#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011576 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011577#endif
11578#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011579 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011580#endif
11581#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011583#endif
11584#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011585 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011586#endif
Fred Draked86ed291999-12-15 15:34:33 +000011587#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011588 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011589#endif
Fred Drakec9680921999-12-13 16:37:25 +000011590#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011591 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011592#endif
Fred Draked86ed291999-12-15 15:34:33 +000011593#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011595#endif
11596#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011597 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011598#endif
11599#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011600 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011601#endif
11602#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011603 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011604#endif
Fred Drakec9680921999-12-13 16:37:25 +000011605#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011606 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011607#endif
11608#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011609 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011610#endif
11611#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011612 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011613#endif
11614#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011615 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011616#endif
11617#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011618 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011619#endif
11620#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011621 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011622#endif
11623#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011624 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011625#endif
11626#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011627 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011628#endif
11629#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011630 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011631#endif
11632#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011633 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011634#endif
11635#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011636 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011637#endif
11638#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011639 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011640#endif
11641#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011642 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011643#endif
11644#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011645 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011646#endif
11647#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011648 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011649#endif
11650#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011651 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011652#endif
Fred Draked86ed291999-12-15 15:34:33 +000011653#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011654 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011655#endif
11656#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011657 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011658#endif
11659#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011660 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011661#endif
11662#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011663 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011664#endif
11665#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011666 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011667#endif
11668#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011669 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011670#endif
11671#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011672 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011673#endif
11674#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011675 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011676#endif
11677#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011678 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011679#endif
11680#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011681 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011682#endif
11683#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011684 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011685#endif
11686#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011687 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011688#endif
11689#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011690 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011691#endif
Fred Drakec9680921999-12-13 16:37:25 +000011692};
11693
11694static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011695conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011696{
11697 return conv_confname(arg, valuep, posix_constants_confstr,
11698 sizeof(posix_constants_confstr)
11699 / sizeof(struct constdef));
11700}
11701
Larry Hastings2f936352014-08-05 14:04:04 +100011702
11703/*[clinic input]
11704os.confstr
11705
11706 name: confstr_confname
11707 /
11708
11709Return a string-valued system configuration variable.
11710[clinic start generated code]*/
11711
Larry Hastings2f936352014-08-05 14:04:04 +100011712static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011713os_confstr_impl(PyObject *module, int name)
11714/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011715{
11716 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011717 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011718 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011719
Victor Stinnercb043522010-09-10 23:49:04 +000011720 errno = 0;
11721 len = confstr(name, buffer, sizeof(buffer));
11722 if (len == 0) {
11723 if (errno) {
11724 posix_error();
11725 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011726 }
11727 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011728 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011729 }
11730 }
Victor Stinnercb043522010-09-10 23:49:04 +000011731
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011732 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011733 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011734 char *buf = PyMem_Malloc(len);
11735 if (buf == NULL)
11736 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011737 len2 = confstr(name, buf, len);
11738 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011739 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011740 PyMem_Free(buf);
11741 }
11742 else
11743 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011744 return result;
11745}
Larry Hastings2f936352014-08-05 14:04:04 +100011746#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011747
11748
11749#ifdef HAVE_SYSCONF
11750static struct constdef posix_constants_sysconf[] = {
11751#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011752 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011753#endif
11754#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011755 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011756#endif
11757#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011758 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011759#endif
11760#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011761 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011762#endif
11763#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011764 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011765#endif
11766#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011767 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011768#endif
11769#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011770 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011771#endif
11772#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011773 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011774#endif
11775#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011776 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011777#endif
11778#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011779 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011780#endif
Fred Draked86ed291999-12-15 15:34:33 +000011781#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011782 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011783#endif
11784#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011785 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011786#endif
Fred Drakec9680921999-12-13 16:37:25 +000011787#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011788 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011789#endif
Fred Drakec9680921999-12-13 16:37:25 +000011790#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011791 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011792#endif
11793#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011794 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011795#endif
11796#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011797 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011798#endif
11799#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011800 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011801#endif
11802#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011803 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011804#endif
Fred Draked86ed291999-12-15 15:34:33 +000011805#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011806 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011807#endif
Fred Drakec9680921999-12-13 16:37:25 +000011808#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011809 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011810#endif
11811#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011812 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011813#endif
11814#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011815 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011816#endif
11817#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011818 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011819#endif
11820#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011821 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011822#endif
Fred Draked86ed291999-12-15 15:34:33 +000011823#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011824 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011825#endif
Fred Drakec9680921999-12-13 16:37:25 +000011826#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011827 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011828#endif
11829#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011830 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011831#endif
11832#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011833 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011834#endif
11835#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011836 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011837#endif
11838#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011839 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011840#endif
11841#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011842 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011843#endif
11844#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011845 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011846#endif
11847#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011848 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011849#endif
11850#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011851 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011852#endif
11853#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011854 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011855#endif
11856#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011857 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011858#endif
11859#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011860 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011861#endif
11862#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011863 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011864#endif
11865#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011866 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011867#endif
11868#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011869 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011870#endif
11871#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011872 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011873#endif
11874#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011875 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011876#endif
11877#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011878 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011879#endif
11880#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011881 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011882#endif
11883#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011884 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011885#endif
11886#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011887 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011888#endif
11889#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011890 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011891#endif
11892#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011893 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011894#endif
Fred Draked86ed291999-12-15 15:34:33 +000011895#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011896 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011897#endif
Fred Drakec9680921999-12-13 16:37:25 +000011898#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011899 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011900#endif
11901#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011902 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011903#endif
11904#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011905 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011906#endif
Fred Draked86ed291999-12-15 15:34:33 +000011907#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011908 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011909#endif
Fred Drakec9680921999-12-13 16:37:25 +000011910#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011911 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011912#endif
Fred Draked86ed291999-12-15 15:34:33 +000011913#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011914 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011915#endif
11916#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011917 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011918#endif
Fred Drakec9680921999-12-13 16:37:25 +000011919#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011920 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011921#endif
11922#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011923 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011924#endif
11925#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011926 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011927#endif
11928#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011929 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011930#endif
Fred Draked86ed291999-12-15 15:34:33 +000011931#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011932 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011933#endif
Fred Drakec9680921999-12-13 16:37:25 +000011934#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011935 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011936#endif
11937#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011938 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011939#endif
11940#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011941 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011942#endif
11943#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011944 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011945#endif
11946#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011947 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011948#endif
11949#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011950 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011951#endif
11952#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011953 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011954#endif
Fred Draked86ed291999-12-15 15:34:33 +000011955#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011956 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011957#endif
Fred Drakec9680921999-12-13 16:37:25 +000011958#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011959 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011960#endif
11961#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011962 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011963#endif
Fred Draked86ed291999-12-15 15:34:33 +000011964#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011965 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011966#endif
Fred Drakec9680921999-12-13 16:37:25 +000011967#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011968 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011969#endif
11970#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011971 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011972#endif
11973#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011974 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011975#endif
11976#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011977 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011978#endif
11979#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011980 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011981#endif
11982#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011983 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011984#endif
11985#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011986 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011987#endif
11988#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011989 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011990#endif
11991#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011992 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011993#endif
Fred Draked86ed291999-12-15 15:34:33 +000011994#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011995 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011996#endif
11997#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011998 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000011999#endif
Fred Drakec9680921999-12-13 16:37:25 +000012000#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000012001 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000012002#endif
12003#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012004 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012005#endif
12006#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012007 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012008#endif
12009#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012010 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012011#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030012012#ifdef _SC_AIX_REALMEM
12013 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
12014#endif
Fred Drakec9680921999-12-13 16:37:25 +000012015#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012016 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012017#endif
12018#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000012019 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000012020#endif
12021#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000012022 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000012023#endif
12024#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000012025 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000012026#endif
12027#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012028 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000012029#endif
12030#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012031 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000012032#endif
12033#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000012034 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000012035#endif
12036#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012037 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000012038#endif
12039#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012040 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000012041#endif
12042#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000012043 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000012044#endif
12045#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000012046 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000012047#endif
12048#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000012049 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000012050#endif
12051#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000012052 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000012053#endif
12054#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012055 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012056#endif
12057#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012058 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012059#endif
12060#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000012061 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000012062#endif
12063#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012064 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012065#endif
12066#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012067 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012068#endif
12069#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000012070 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000012071#endif
12072#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012073 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012074#endif
12075#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012076 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012077#endif
12078#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012079 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000012080#endif
12081#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000012082 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000012083#endif
12084#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012085 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012086#endif
12087#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012088 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012089#endif
12090#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012091 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000012092#endif
12093#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012094 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012095#endif
12096#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012097 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012098#endif
12099#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012100 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012101#endif
12102#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012103 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012104#endif
12105#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012106 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012107#endif
Fred Draked86ed291999-12-15 15:34:33 +000012108#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000012109 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000012110#endif
Fred Drakec9680921999-12-13 16:37:25 +000012111#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000012112 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000012113#endif
12114#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012115 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012116#endif
12117#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000012118 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000012119#endif
12120#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012121 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012122#endif
12123#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012124 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012125#endif
12126#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012127 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012128#endif
12129#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000012130 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000012131#endif
12132#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012133 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012134#endif
12135#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012136 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012137#endif
12138#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012139 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012140#endif
12141#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012142 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012143#endif
12144#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012145 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000012146#endif
12147#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012148 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000012149#endif
12150#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000012151 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000012152#endif
12153#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012154 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012155#endif
12156#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012157 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012158#endif
12159#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012160 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012161#endif
12162#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000012163 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000012164#endif
12165#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012166 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012167#endif
12168#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012169 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012170#endif
12171#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012172 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012173#endif
12174#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012175 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012176#endif
12177#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012178 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012179#endif
12180#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012181 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012182#endif
12183#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000012184 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000012185#endif
12186#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012187 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012188#endif
12189#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012190 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012191#endif
12192#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012193 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012194#endif
12195#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012196 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000012197#endif
12198#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000012199 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000012200#endif
12201#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012202 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012203#endif
12204#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000012205 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000012206#endif
12207#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012208 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012209#endif
12210#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000012211 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000012212#endif
12213#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000012214 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000012215#endif
12216#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000012217 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000012218#endif
12219#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012220 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000012221#endif
12222#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012223 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012224#endif
12225#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000012226 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000012227#endif
12228#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000012229 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000012230#endif
12231#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012232 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012233#endif
12234#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012235 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012236#endif
12237#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000012238 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000012239#endif
12240#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000012241 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000012242#endif
12243#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000012244 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000012245#endif
12246};
12247
12248static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012249conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000012250{
12251 return conv_confname(arg, valuep, posix_constants_sysconf,
12252 sizeof(posix_constants_sysconf)
12253 / sizeof(struct constdef));
12254}
12255
Larry Hastings2f936352014-08-05 14:04:04 +100012256
12257/*[clinic input]
12258os.sysconf -> long
12259 name: sysconf_confname
12260 /
12261
12262Return an integer-valued system configuration variable.
12263[clinic start generated code]*/
12264
Larry Hastings2f936352014-08-05 14:04:04 +100012265static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012266os_sysconf_impl(PyObject *module, int name)
12267/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012268{
12269 long value;
12270
12271 errno = 0;
12272 value = sysconf(name);
12273 if (value == -1 && errno != 0)
12274 posix_error();
12275 return value;
12276}
12277#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000012278
12279
Fred Drakebec628d1999-12-15 18:31:10 +000012280/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020012281 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000012282 * the exported dictionaries that are used to publish information about the
12283 * names available on the host platform.
12284 *
12285 * Sorting the table at runtime ensures that the table is properly ordered
12286 * when used, even for platforms we're not able to test on. It also makes
12287 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000012288 */
Fred Drakebec628d1999-12-15 18:31:10 +000012289
12290static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012291cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000012292{
12293 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012294 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000012295 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012296 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000012297
12298 return strcmp(c1->name, c2->name);
12299}
12300
12301static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012302setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012303 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012304{
Fred Drakebec628d1999-12-15 18:31:10 +000012305 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000012306 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000012307
12308 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
12309 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000012310 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000012311 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012312
Barry Warsaw3155db32000-04-13 15:20:40 +000012313 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000012314 PyObject *o = PyLong_FromLong(table[i].value);
12315 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
12316 Py_XDECREF(o);
12317 Py_DECREF(d);
12318 return -1;
12319 }
12320 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000012321 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000012322 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000012323}
12324
Fred Drakebec628d1999-12-15 18:31:10 +000012325/* Return -1 on failure, 0 on success. */
12326static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000012327setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012328{
12329#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000012330 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000012331 sizeof(posix_constants_pathconf)
12332 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012333 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012334 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012335#endif
12336#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000012337 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000012338 sizeof(posix_constants_confstr)
12339 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012340 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012341 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012342#endif
12343#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000012344 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000012345 sizeof(posix_constants_sysconf)
12346 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012347 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012348 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012349#endif
Fred Drakebec628d1999-12-15 18:31:10 +000012350 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000012351}
Fred Draked86ed291999-12-15 15:34:33 +000012352
12353
Larry Hastings2f936352014-08-05 14:04:04 +100012354/*[clinic input]
12355os.abort
12356
12357Abort the interpreter immediately.
12358
12359This function 'dumps core' or otherwise fails in the hardest way possible
12360on the hosting operating system. This function never returns.
12361[clinic start generated code]*/
12362
Larry Hastings2f936352014-08-05 14:04:04 +100012363static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012364os_abort_impl(PyObject *module)
12365/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012366{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012367 abort();
12368 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010012369#ifndef __clang__
12370 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
12371 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
12372 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012373 Py_FatalError("abort() called from Python code didn't abort!");
12374 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010012375#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012376}
Fred Drakebec628d1999-12-15 18:31:10 +000012377
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000012378#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012379/* Grab ShellExecute dynamically from shell32 */
12380static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012381static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
12382 LPCWSTR, INT);
12383static int
12384check_ShellExecute()
12385{
12386 HINSTANCE hShell32;
12387
12388 /* only recheck */
12389 if (-1 == has_ShellExecute) {
12390 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070012391 /* Security note: this call is not vulnerable to "DLL hijacking".
12392 SHELL32 is part of "KnownDLLs" and so Windows always load
12393 the system SHELL32.DLL, even if there is another SHELL32.DLL
12394 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080012395 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080012396 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080012397 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
12398 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070012399 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012400 } else {
12401 has_ShellExecute = 0;
12402 }
Tony Roberts4860f012019-02-02 18:16:42 +010012403 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012404 }
12405 return has_ShellExecute;
12406}
12407
12408
Steve Dowercc16be82016-09-08 10:35:16 -070012409/*[clinic input]
12410os.startfile
12411 filepath: path_t
12412 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000012413
Steve Dowercc16be82016-09-08 10:35:16 -070012414Start a file with its associated application.
12415
12416When "operation" is not specified or "open", this acts like
12417double-clicking the file in Explorer, or giving the file name as an
12418argument to the DOS "start" command: the file is opened with whatever
12419application (if any) its extension is associated.
12420When another "operation" is given, it specifies what should be done with
12421the file. A typical operation is "print".
12422
12423startfile returns as soon as the associated application is launched.
12424There is no option to wait for the application to close, and no way
12425to retrieve the application's exit status.
12426
12427The filepath is relative to the current directory. If you want to use
12428an absolute path, make sure the first character is not a slash ("/");
12429the underlying Win32 ShellExecute function doesn't work if it is.
12430[clinic start generated code]*/
12431
12432static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020012433os_startfile_impl(PyObject *module, path_t *filepath,
12434 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030012435/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070012436{
12437 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012438
12439 if(!check_ShellExecute()) {
12440 /* If the OS doesn't have ShellExecute, return a
12441 NotImplementedError. */
12442 return PyErr_Format(PyExc_NotImplementedError,
12443 "startfile not available on this platform");
12444 }
12445
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012446 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080012447 return NULL;
12448 }
12449
Victor Stinner8c62be82010-05-06 00:08:46 +000012450 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070012451 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080012452 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000012453 Py_END_ALLOW_THREADS
12454
Victor Stinner8c62be82010-05-06 00:08:46 +000012455 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070012456 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020012457 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012458 }
Steve Dowercc16be82016-09-08 10:35:16 -070012459 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000012460}
Larry Hastings2f936352014-08-05 14:04:04 +100012461#endif /* MS_WINDOWS */
12462
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012463
Martin v. Löwis438b5342002-12-27 10:16:42 +000012464#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100012465/*[clinic input]
12466os.getloadavg
12467
12468Return average recent system load information.
12469
12470Return the number of processes in the system run queue averaged over
12471the last 1, 5, and 15 minutes as a tuple of three floats.
12472Raises OSError if the load average was unobtainable.
12473[clinic start generated code]*/
12474
Larry Hastings2f936352014-08-05 14:04:04 +100012475static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012476os_getloadavg_impl(PyObject *module)
12477/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000012478{
12479 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000012480 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000012481 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
12482 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000012483 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000012484 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000012485}
Larry Hastings2f936352014-08-05 14:04:04 +100012486#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000012487
Larry Hastings2f936352014-08-05 14:04:04 +100012488
12489/*[clinic input]
12490os.device_encoding
12491 fd: int
12492
12493Return a string describing the encoding of a terminal's file descriptor.
12494
12495The file descriptor must be attached to a terminal.
12496If the device is not a terminal, return None.
12497[clinic start generated code]*/
12498
Larry Hastings2f936352014-08-05 14:04:04 +100012499static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012500os_device_encoding_impl(PyObject *module, int fd)
12501/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012502{
Brett Cannonefb00c02012-02-29 18:31:31 -050012503 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000012504}
12505
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012506
Larry Hastings2f936352014-08-05 14:04:04 +100012507#ifdef HAVE_SETRESUID
12508/*[clinic input]
12509os.setresuid
12510
12511 ruid: uid_t
12512 euid: uid_t
12513 suid: uid_t
12514 /
12515
12516Set the current process's real, effective, and saved user ids.
12517[clinic start generated code]*/
12518
Larry Hastings2f936352014-08-05 14:04:04 +100012519static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012520os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12521/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012522{
Victor Stinner8c62be82010-05-06 00:08:46 +000012523 if (setresuid(ruid, euid, suid) < 0)
12524 return posix_error();
12525 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012526}
Larry Hastings2f936352014-08-05 14:04:04 +100012527#endif /* HAVE_SETRESUID */
12528
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012529
12530#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012531/*[clinic input]
12532os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012533
Larry Hastings2f936352014-08-05 14:04:04 +100012534 rgid: gid_t
12535 egid: gid_t
12536 sgid: gid_t
12537 /
12538
12539Set the current process's real, effective, and saved group ids.
12540[clinic start generated code]*/
12541
Larry Hastings2f936352014-08-05 14:04:04 +100012542static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012543os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12544/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012545{
Victor Stinner8c62be82010-05-06 00:08:46 +000012546 if (setresgid(rgid, egid, sgid) < 0)
12547 return posix_error();
12548 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012549}
Larry Hastings2f936352014-08-05 14:04:04 +100012550#endif /* HAVE_SETRESGID */
12551
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012552
12553#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012554/*[clinic input]
12555os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012556
Larry Hastings2f936352014-08-05 14:04:04 +100012557Return a tuple of the current process's real, effective, and saved user ids.
12558[clinic start generated code]*/
12559
Larry Hastings2f936352014-08-05 14:04:04 +100012560static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012561os_getresuid_impl(PyObject *module)
12562/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012563{
Victor Stinner8c62be82010-05-06 00:08:46 +000012564 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012565 if (getresuid(&ruid, &euid, &suid) < 0)
12566 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012567 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12568 _PyLong_FromUid(euid),
12569 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012570}
Larry Hastings2f936352014-08-05 14:04:04 +100012571#endif /* HAVE_GETRESUID */
12572
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012573
12574#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012575/*[clinic input]
12576os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012577
Larry Hastings2f936352014-08-05 14:04:04 +100012578Return a tuple of the current process's real, effective, and saved group ids.
12579[clinic start generated code]*/
12580
Larry Hastings2f936352014-08-05 14:04:04 +100012581static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012582os_getresgid_impl(PyObject *module)
12583/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012584{
12585 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012586 if (getresgid(&rgid, &egid, &sgid) < 0)
12587 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012588 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12589 _PyLong_FromGid(egid),
12590 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012591}
Larry Hastings2f936352014-08-05 14:04:04 +100012592#endif /* HAVE_GETRESGID */
12593
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012594
Benjamin Peterson9428d532011-09-14 11:45:52 -040012595#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012596/*[clinic input]
12597os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012598
Larry Hastings2f936352014-08-05 14:04:04 +100012599 path: path_t(allow_fd=True)
12600 attribute: path_t
12601 *
12602 follow_symlinks: bool = True
12603
12604Return the value of extended attribute attribute on path.
12605
BNMetricsb9427072018-11-02 15:20:19 +000012606path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012607If follow_symlinks is False, and the last element of the path is a symbolic
12608 link, getxattr will examine the symbolic link itself instead of the file
12609 the link points to.
12610
12611[clinic start generated code]*/
12612
Larry Hastings2f936352014-08-05 14:04:04 +100012613static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012614os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012615 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012616/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012617{
12618 Py_ssize_t i;
12619 PyObject *buffer = NULL;
12620
12621 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12622 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012623
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012624 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12625 return NULL;
12626 }
12627
Larry Hastings9cf065c2012-06-22 16:30:09 -070012628 for (i = 0; ; i++) {
12629 void *ptr;
12630 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012631 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012632 Py_ssize_t buffer_size = buffer_sizes[i];
12633 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012634 path_error(path);
12635 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012636 }
12637 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12638 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012639 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012640 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012641
Larry Hastings9cf065c2012-06-22 16:30:09 -070012642 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012643 if (path->fd >= 0)
12644 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012645 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012646 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012647 else
Larry Hastings2f936352014-08-05 14:04:04 +100012648 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012649 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012650
Larry Hastings9cf065c2012-06-22 16:30:09 -070012651 if (result < 0) {
12652 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012653 if (errno == ERANGE)
12654 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012655 path_error(path);
12656 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012657 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012658
Larry Hastings9cf065c2012-06-22 16:30:09 -070012659 if (result != buffer_size) {
12660 /* Can only shrink. */
12661 _PyBytes_Resize(&buffer, result);
12662 }
12663 break;
12664 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012665
Larry Hastings9cf065c2012-06-22 16:30:09 -070012666 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012667}
12668
Larry Hastings2f936352014-08-05 14:04:04 +100012669
12670/*[clinic input]
12671os.setxattr
12672
12673 path: path_t(allow_fd=True)
12674 attribute: path_t
12675 value: Py_buffer
12676 flags: int = 0
12677 *
12678 follow_symlinks: bool = True
12679
12680Set extended attribute attribute on path to value.
12681
BNMetricsb9427072018-11-02 15:20:19 +000012682path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012683If follow_symlinks is False, and the last element of the path is a symbolic
12684 link, setxattr will modify the symbolic link itself instead of the file
12685 the link points to.
12686
12687[clinic start generated code]*/
12688
Benjamin Peterson799bd802011-08-31 22:15:17 -040012689static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012690os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012691 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012692/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012693{
Larry Hastings2f936352014-08-05 14:04:04 +100012694 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012695
Larry Hastings2f936352014-08-05 14:04:04 +100012696 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012697 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012698
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012699 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12700 value->buf, value->len, flags) < 0) {
12701 return NULL;
12702 }
12703
Benjamin Peterson799bd802011-08-31 22:15:17 -040012704 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012705 if (path->fd > -1)
12706 result = fsetxattr(path->fd, attribute->narrow,
12707 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012708 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012709 result = setxattr(path->narrow, attribute->narrow,
12710 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012711 else
Larry Hastings2f936352014-08-05 14:04:04 +100012712 result = lsetxattr(path->narrow, attribute->narrow,
12713 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012714 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012715
Larry Hastings9cf065c2012-06-22 16:30:09 -070012716 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012717 path_error(path);
12718 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012719 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012720
Larry Hastings2f936352014-08-05 14:04:04 +100012721 Py_RETURN_NONE;
12722}
12723
12724
12725/*[clinic input]
12726os.removexattr
12727
12728 path: path_t(allow_fd=True)
12729 attribute: path_t
12730 *
12731 follow_symlinks: bool = True
12732
12733Remove extended attribute attribute on path.
12734
BNMetricsb9427072018-11-02 15:20:19 +000012735path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012736If follow_symlinks is False, and the last element of the path is a symbolic
12737 link, removexattr will modify the symbolic link itself instead of the file
12738 the link points to.
12739
12740[clinic start generated code]*/
12741
Larry Hastings2f936352014-08-05 14:04:04 +100012742static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012743os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012744 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012745/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012746{
12747 ssize_t result;
12748
12749 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12750 return NULL;
12751
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012752 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12753 return NULL;
12754 }
12755
Larry Hastings2f936352014-08-05 14:04:04 +100012756 Py_BEGIN_ALLOW_THREADS;
12757 if (path->fd > -1)
12758 result = fremovexattr(path->fd, attribute->narrow);
12759 else if (follow_symlinks)
12760 result = removexattr(path->narrow, attribute->narrow);
12761 else
12762 result = lremovexattr(path->narrow, attribute->narrow);
12763 Py_END_ALLOW_THREADS;
12764
12765 if (result) {
12766 return path_error(path);
12767 }
12768
12769 Py_RETURN_NONE;
12770}
12771
12772
12773/*[clinic input]
12774os.listxattr
12775
12776 path: path_t(allow_fd=True, nullable=True) = None
12777 *
12778 follow_symlinks: bool = True
12779
12780Return a list of extended attributes on path.
12781
BNMetricsb9427072018-11-02 15:20:19 +000012782path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012783if path is None, listxattr will examine the current directory.
12784If follow_symlinks is False, and the last element of the path is a symbolic
12785 link, listxattr will examine the symbolic link itself instead of the file
12786 the link points to.
12787[clinic start generated code]*/
12788
Larry Hastings2f936352014-08-05 14:04:04 +100012789static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012790os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012791/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012792{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012793 Py_ssize_t i;
12794 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012795 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012796 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012797
Larry Hastings2f936352014-08-05 14:04:04 +100012798 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012799 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012800
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012801 if (PySys_Audit("os.listxattr", "(O)",
12802 path->object ? path->object : Py_None) < 0) {
12803 return NULL;
12804 }
12805
Larry Hastings2f936352014-08-05 14:04:04 +100012806 name = path->narrow ? path->narrow : ".";
12807
Larry Hastings9cf065c2012-06-22 16:30:09 -070012808 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012809 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012810 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012811 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012812 Py_ssize_t buffer_size = buffer_sizes[i];
12813 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012814 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012815 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012816 break;
12817 }
12818 buffer = PyMem_MALLOC(buffer_size);
12819 if (!buffer) {
12820 PyErr_NoMemory();
12821 break;
12822 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012823
Larry Hastings9cf065c2012-06-22 16:30:09 -070012824 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012825 if (path->fd > -1)
12826 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012827 else if (follow_symlinks)
12828 length = listxattr(name, buffer, buffer_size);
12829 else
12830 length = llistxattr(name, buffer, buffer_size);
12831 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012832
Larry Hastings9cf065c2012-06-22 16:30:09 -070012833 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012834 if (errno == ERANGE) {
12835 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012836 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012837 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012838 }
Larry Hastings2f936352014-08-05 14:04:04 +100012839 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012840 break;
12841 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012842
Larry Hastings9cf065c2012-06-22 16:30:09 -070012843 result = PyList_New(0);
12844 if (!result) {
12845 goto exit;
12846 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012847
Larry Hastings9cf065c2012-06-22 16:30:09 -070012848 end = buffer + length;
12849 for (trace = start = buffer; trace != end; trace++) {
12850 if (!*trace) {
12851 int error;
12852 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12853 trace - start);
12854 if (!attribute) {
12855 Py_DECREF(result);
12856 result = NULL;
12857 goto exit;
12858 }
12859 error = PyList_Append(result, attribute);
12860 Py_DECREF(attribute);
12861 if (error) {
12862 Py_DECREF(result);
12863 result = NULL;
12864 goto exit;
12865 }
12866 start = trace + 1;
12867 }
12868 }
12869 break;
12870 }
12871exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012872 if (buffer)
12873 PyMem_FREE(buffer);
12874 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012875}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012876#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012877
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012878
Larry Hastings2f936352014-08-05 14:04:04 +100012879/*[clinic input]
12880os.urandom
12881
12882 size: Py_ssize_t
12883 /
12884
12885Return a bytes object containing random bytes suitable for cryptographic use.
12886[clinic start generated code]*/
12887
Larry Hastings2f936352014-08-05 14:04:04 +100012888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012889os_urandom_impl(PyObject *module, Py_ssize_t size)
12890/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012891{
12892 PyObject *bytes;
12893 int result;
12894
Georg Brandl2fb477c2012-02-21 00:33:36 +010012895 if (size < 0)
12896 return PyErr_Format(PyExc_ValueError,
12897 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012898 bytes = PyBytes_FromStringAndSize(NULL, size);
12899 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012900 return NULL;
12901
Victor Stinnere66987e2016-09-06 16:33:52 -070012902 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012903 if (result == -1) {
12904 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012905 return NULL;
12906 }
Larry Hastings2f936352014-08-05 14:04:04 +100012907 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012908}
12909
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012910#ifdef HAVE_MEMFD_CREATE
12911/*[clinic input]
12912os.memfd_create
12913
12914 name: FSConverter
12915 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12916
12917[clinic start generated code]*/
12918
12919static PyObject *
12920os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12921/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12922{
12923 int fd;
12924 const char *bytes = PyBytes_AS_STRING(name);
12925 Py_BEGIN_ALLOW_THREADS
12926 fd = memfd_create(bytes, flags);
12927 Py_END_ALLOW_THREADS
12928 if (fd == -1) {
12929 return PyErr_SetFromErrno(PyExc_OSError);
12930 }
12931 return PyLong_FromLong(fd);
12932}
12933#endif
12934
Christian Heimescd9fed62020-11-13 19:48:52 +010012935#ifdef HAVE_EVENTFD
12936/*[clinic input]
12937os.eventfd
12938
12939 initval: unsigned_int
12940 flags: int(c_default="EFD_CLOEXEC") = EFD_CLOEXEC
12941
12942Creates and returns an event notification file descriptor.
12943[clinic start generated code]*/
12944
12945static PyObject *
12946os_eventfd_impl(PyObject *module, unsigned int initval, int flags)
12947/*[clinic end generated code: output=ce9c9bbd1446f2de input=66203e3c50c4028b]*/
12948
12949{
12950 /* initval is limited to uint32_t, internal counter is uint64_t */
12951 int fd;
12952 Py_BEGIN_ALLOW_THREADS
12953 fd = eventfd(initval, flags);
12954 Py_END_ALLOW_THREADS
12955 if (fd == -1) {
12956 return PyErr_SetFromErrno(PyExc_OSError);
12957 }
12958 return PyLong_FromLong(fd);
12959}
12960
12961/*[clinic input]
12962os.eventfd_read
12963
12964 fd: fildes
12965
12966Read eventfd value
12967[clinic start generated code]*/
12968
12969static PyObject *
12970os_eventfd_read_impl(PyObject *module, int fd)
12971/*[clinic end generated code: output=8f2c7b59a3521fd1 input=110f8b57fa596afe]*/
12972{
12973 eventfd_t value;
12974 int result;
12975 Py_BEGIN_ALLOW_THREADS
12976 result = eventfd_read(fd, &value);
12977 Py_END_ALLOW_THREADS
12978 if (result == -1) {
12979 return PyErr_SetFromErrno(PyExc_OSError);
12980 }
12981 return PyLong_FromUnsignedLongLong(value);
12982}
12983
12984/*[clinic input]
12985os.eventfd_write
12986
12987 fd: fildes
12988 value: unsigned_long_long
12989
12990Write eventfd value.
12991[clinic start generated code]*/
12992
12993static PyObject *
12994os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value)
12995/*[clinic end generated code: output=bebd9040bbf987f5 input=156de8555be5a949]*/
12996{
12997 int result;
12998 Py_BEGIN_ALLOW_THREADS
12999 result = eventfd_write(fd, value);
13000 Py_END_ALLOW_THREADS
13001 if (result == -1) {
13002 return PyErr_SetFromErrno(PyExc_OSError);
13003 }
13004 Py_RETURN_NONE;
13005}
13006#endif /* HAVE_EVENTFD */
13007
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013008/* Terminal size querying */
13009
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013010PyDoc_STRVAR(TerminalSize_docstring,
13011 "A tuple of (columns, lines) for holding terminal window size");
13012
13013static PyStructSequence_Field TerminalSize_fields[] = {
13014 {"columns", "width of the terminal window in characters"},
13015 {"lines", "height of the terminal window in characters"},
13016 {NULL, NULL}
13017};
13018
13019static PyStructSequence_Desc TerminalSize_desc = {
13020 "os.terminal_size",
13021 TerminalSize_docstring,
13022 TerminalSize_fields,
13023 2,
13024};
13025
13026#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013027/*[clinic input]
13028os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013029
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013030 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
13031 /
13032
13033Return the size of the terminal window as (columns, lines).
13034
13035The optional argument fd (default standard output) specifies
13036which file descriptor should be queried.
13037
13038If the file descriptor is not connected to a terminal, an OSError
13039is thrown.
13040
13041This function will only be defined if an implementation is
13042available for this system.
13043
13044shutil.get_terminal_size is the high-level function which should
13045normally be used, os.get_terminal_size is the low-level implementation.
13046[clinic start generated code]*/
13047
13048static PyObject *
13049os_get_terminal_size_impl(PyObject *module, int fd)
13050/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013051{
13052 int columns, lines;
13053 PyObject *termsize;
13054
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013055 /* Under some conditions stdout may not be connected and
13056 * fileno(stdout) may point to an invalid file descriptor. For example
13057 * GUI apps don't have valid standard streams by default.
13058 *
13059 * If this happens, and the optional fd argument is not present,
13060 * the ioctl below will fail returning EBADF. This is what we want.
13061 */
13062
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013063#ifdef TERMSIZE_USE_IOCTL
13064 {
13065 struct winsize w;
13066 if (ioctl(fd, TIOCGWINSZ, &w))
13067 return PyErr_SetFromErrno(PyExc_OSError);
13068 columns = w.ws_col;
13069 lines = w.ws_row;
13070 }
13071#endif /* TERMSIZE_USE_IOCTL */
13072
13073#ifdef TERMSIZE_USE_CONIO
13074 {
13075 DWORD nhandle;
13076 HANDLE handle;
13077 CONSOLE_SCREEN_BUFFER_INFO csbi;
13078 switch (fd) {
13079 case 0: nhandle = STD_INPUT_HANDLE;
13080 break;
13081 case 1: nhandle = STD_OUTPUT_HANDLE;
13082 break;
13083 case 2: nhandle = STD_ERROR_HANDLE;
13084 break;
13085 default:
13086 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
13087 }
13088 handle = GetStdHandle(nhandle);
13089 if (handle == NULL)
13090 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
13091 if (handle == INVALID_HANDLE_VALUE)
13092 return PyErr_SetFromWindowsErr(0);
13093
13094 if (!GetConsoleScreenBufferInfo(handle, &csbi))
13095 return PyErr_SetFromWindowsErr(0);
13096
13097 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
13098 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
13099 }
13100#endif /* TERMSIZE_USE_CONIO */
13101
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013102 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013103 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013104 if (termsize == NULL)
13105 return NULL;
13106 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
13107 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
13108 if (PyErr_Occurred()) {
13109 Py_DECREF(termsize);
13110 return NULL;
13111 }
13112 return termsize;
13113}
13114#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
13115
Larry Hastings2f936352014-08-05 14:04:04 +100013116
13117/*[clinic input]
13118os.cpu_count
13119
Charles-François Natali80d62e62015-08-13 20:37:08 +010013120Return the number of CPUs in the system; return None if indeterminable.
13121
13122This number is not equivalent to the number of CPUs the current process can
13123use. The number of usable CPUs can be obtained with
13124``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100013125[clinic start generated code]*/
13126
Larry Hastings2f936352014-08-05 14:04:04 +100013127static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013128os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013129/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013130{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013131 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013132#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010013133 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013134#elif defined(__hpux)
13135 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
13136#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
13137 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
pxinwr3405e052020-08-07 13:21:52 +080013138#elif defined(__VXWORKS__)
13139 ncpu = _Py_popcount32(vxCpuEnabledGet());
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013140#elif defined(__DragonFly__) || \
13141 defined(__OpenBSD__) || \
13142 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013143 defined(__NetBSD__) || \
13144 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020013145 int mib[2];
13146 size_t len = sizeof(ncpu);
13147 mib[0] = CTL_HW;
13148 mib[1] = HW_NCPU;
13149 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
13150 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013151#endif
13152 if (ncpu >= 1)
13153 return PyLong_FromLong(ncpu);
13154 else
13155 Py_RETURN_NONE;
13156}
13157
Victor Stinnerdaf45552013-08-28 00:53:59 +020013158
Larry Hastings2f936352014-08-05 14:04:04 +100013159/*[clinic input]
13160os.get_inheritable -> bool
13161
13162 fd: int
13163 /
13164
13165Get the close-on-exe flag of the specified file descriptor.
13166[clinic start generated code]*/
13167
Larry Hastings2f936352014-08-05 14:04:04 +100013168static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013169os_get_inheritable_impl(PyObject *module, int fd)
13170/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013171{
Steve Dower8fc89802015-04-12 00:26:27 -040013172 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040013173 _Py_BEGIN_SUPPRESS_IPH
13174 return_value = _Py_get_inheritable(fd);
13175 _Py_END_SUPPRESS_IPH
13176 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100013177}
13178
13179
13180/*[clinic input]
13181os.set_inheritable
13182 fd: int
13183 inheritable: int
13184 /
13185
13186Set the inheritable flag of the specified file descriptor.
13187[clinic start generated code]*/
13188
Larry Hastings2f936352014-08-05 14:04:04 +100013189static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013190os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
13191/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020013192{
Steve Dower8fc89802015-04-12 00:26:27 -040013193 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013194
Steve Dower8fc89802015-04-12 00:26:27 -040013195 _Py_BEGIN_SUPPRESS_IPH
13196 result = _Py_set_inheritable(fd, inheritable, NULL);
13197 _Py_END_SUPPRESS_IPH
13198 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020013199 return NULL;
13200 Py_RETURN_NONE;
13201}
13202
13203
13204#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100013205/*[clinic input]
13206os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070013207 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013208 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020013209
Larry Hastings2f936352014-08-05 14:04:04 +100013210Get the close-on-exe flag of the specified file descriptor.
13211[clinic start generated code]*/
13212
Larry Hastings2f936352014-08-05 14:04:04 +100013213static int
Benjamin Petersonca470632016-09-06 13:47:26 -070013214os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070013215/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013216{
13217 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013218
13219 if (!GetHandleInformation((HANDLE)handle, &flags)) {
13220 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100013221 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013222 }
13223
Larry Hastings2f936352014-08-05 14:04:04 +100013224 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013225}
13226
Victor Stinnerdaf45552013-08-28 00:53:59 +020013227
Larry Hastings2f936352014-08-05 14:04:04 +100013228/*[clinic input]
13229os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070013230 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013231 inheritable: bool
13232 /
13233
13234Set the inheritable flag of the specified handle.
13235[clinic start generated code]*/
13236
Larry Hastings2f936352014-08-05 14:04:04 +100013237static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070013238os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040013239 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070013240/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013241{
13242 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013243 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
13244 PyErr_SetFromWindowsErr(0);
13245 return NULL;
13246 }
13247 Py_RETURN_NONE;
13248}
Larry Hastings2f936352014-08-05 14:04:04 +100013249#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013250
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013251#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013252/*[clinic input]
13253os.get_blocking -> bool
13254 fd: int
13255 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013256
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013257Get the blocking mode of the file descriptor.
13258
13259Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
13260[clinic start generated code]*/
13261
13262static int
13263os_get_blocking_impl(PyObject *module, int fd)
13264/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013265{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013266 int blocking;
13267
Steve Dower8fc89802015-04-12 00:26:27 -040013268 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013269 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040013270 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013271 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013272}
13273
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013274/*[clinic input]
13275os.set_blocking
13276 fd: int
13277 blocking: bool(accept={int})
13278 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013279
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013280Set the blocking mode of the specified file descriptor.
13281
13282Set the O_NONBLOCK flag if blocking is False,
13283clear the O_NONBLOCK flag otherwise.
13284[clinic start generated code]*/
13285
13286static PyObject *
13287os_set_blocking_impl(PyObject *module, int fd, int blocking)
13288/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013289{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013290 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013291
Steve Dower8fc89802015-04-12 00:26:27 -040013292 _Py_BEGIN_SUPPRESS_IPH
13293 result = _Py_set_blocking(fd, blocking);
13294 _Py_END_SUPPRESS_IPH
13295 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013296 return NULL;
13297 Py_RETURN_NONE;
13298}
13299#endif /* !MS_WINDOWS */
13300
13301
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013302/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080013303class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013304[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080013305/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013306
13307typedef struct {
13308 PyObject_HEAD
13309 PyObject *name;
13310 PyObject *path;
13311 PyObject *stat;
13312 PyObject *lstat;
13313#ifdef MS_WINDOWS
13314 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010013315 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010013316 int got_file_index;
13317#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010013318#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013319 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013320#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013321 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013322 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010013323#endif
13324} DirEntry;
13325
Eddie Elizondob3966632019-11-05 07:16:14 -080013326static PyObject *
13327_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
13328{
13329 PyErr_Format(PyExc_TypeError,
13330 "cannot create '%.100s' instances", _PyType_Name(type));
13331 return NULL;
13332}
13333
Victor Stinner6036e442015-03-08 01:58:04 +010013334static void
13335DirEntry_dealloc(DirEntry *entry)
13336{
Eddie Elizondob3966632019-11-05 07:16:14 -080013337 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010013338 Py_XDECREF(entry->name);
13339 Py_XDECREF(entry->path);
13340 Py_XDECREF(entry->stat);
13341 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080013342 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13343 free_func(entry);
13344 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013345}
13346
13347/* Forward reference */
13348static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013349DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13350 int follow_symlinks, unsigned short mode_bits);
Victor Stinner6036e442015-03-08 01:58:04 +010013351
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013352/*[clinic input]
13353os.DirEntry.is_symlink -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013354 defining_class: defining_class
13355 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013356
13357Return True if the entry is a symbolic link; cached per entry.
13358[clinic start generated code]*/
13359
Victor Stinner6036e442015-03-08 01:58:04 +010013360static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013361os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
13362/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013363{
13364#ifdef MS_WINDOWS
13365 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010013366#elif defined(HAVE_DIRENT_D_TYPE)
13367 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013368 if (self->d_type != DT_UNKNOWN)
13369 return self->d_type == DT_LNK;
13370 else
Victor Stinner97f33c32020-05-14 18:05:58 +020013371 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010013372#else
13373 /* POSIX without d_type */
Victor Stinner97f33c32020-05-14 18:05:58 +020013374 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010013375#endif
13376}
13377
13378static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013379DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
Victor Stinner6036e442015-03-08 01:58:04 +010013380{
13381 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013382 STRUCT_STAT st;
13383 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010013384
13385#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013386 if (!PyUnicode_FSDecoder(self->path, &ub))
13387 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013388#if USE_UNICODE_WCHAR_CACHE
13389_Py_COMP_DIAG_PUSH
13390_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013391 const wchar_t *path = PyUnicode_AsUnicode(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013392_Py_COMP_DIAG_POP
13393#else /* USE_UNICODE_WCHAR_CACHE */
13394 wchar_t *path = PyUnicode_AsWideCharString(ub, NULL);
13395 Py_DECREF(ub);
13396#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013397#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013398 if (!PyUnicode_FSConverter(self->path, &ub))
13399 return NULL;
13400 const char *path = PyBytes_AS_STRING(ub);
13401 if (self->dir_fd != DEFAULT_DIR_FD) {
13402#ifdef HAVE_FSTATAT
Ronald Oussoren41761932020-11-08 10:05:27 +010013403 if (HAVE_FSTATAT_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013404 result = fstatat(self->dir_fd, path, &st,
13405 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +010013406 } else
13407
13408#endif /* HAVE_FSTATAT */
13409 {
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013410 Py_DECREF(ub);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013411 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
13412 return NULL;
Ronald Oussoren41761932020-11-08 10:05:27 +010013413 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013414 }
13415 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013416#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013417 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013418 if (follow_symlinks)
13419 result = STAT(path, &st);
13420 else
13421 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013422 }
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013423#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE
13424 PyMem_Free(path);
13425#else /* USE_UNICODE_WCHAR_CACHE */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013426 Py_DECREF(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013427#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013428
13429 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013430 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013431
Victor Stinner97f33c32020-05-14 18:05:58 +020013432 return _pystat_fromstructstat(module, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010013433}
13434
13435static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013436DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
Victor Stinner6036e442015-03-08 01:58:04 +010013437{
13438 if (!self->lstat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013439 PyObject *module = PyType_GetModule(defining_class);
Victor Stinner6036e442015-03-08 01:58:04 +010013440#ifdef MS_WINDOWS
Victor Stinner97f33c32020-05-14 18:05:58 +020013441 self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010013442#else /* POSIX */
Victor Stinner97f33c32020-05-14 18:05:58 +020013443 self->lstat = DirEntry_fetch_stat(module, self, 0);
Victor Stinner6036e442015-03-08 01:58:04 +010013444#endif
13445 }
13446 Py_XINCREF(self->lstat);
13447 return self->lstat;
13448}
13449
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013450/*[clinic input]
13451os.DirEntry.stat
Victor Stinner97f33c32020-05-14 18:05:58 +020013452 defining_class: defining_class
13453 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013454 *
13455 follow_symlinks: bool = True
13456
13457Return stat_result object for the entry; cached per entry.
13458[clinic start generated code]*/
13459
Victor Stinner6036e442015-03-08 01:58:04 +010013460static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013461os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
13462 int follow_symlinks)
13463/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013464{
Victor Stinner97f33c32020-05-14 18:05:58 +020013465 if (!follow_symlinks) {
13466 return DirEntry_get_lstat(defining_class, self);
13467 }
Victor Stinner6036e442015-03-08 01:58:04 +010013468
13469 if (!self->stat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013470 int result = os_DirEntry_is_symlink_impl(self, defining_class);
13471 if (result == -1) {
Victor Stinner6036e442015-03-08 01:58:04 +010013472 return NULL;
Victor Stinner97f33c32020-05-14 18:05:58 +020013473 }
13474 if (result) {
13475 PyObject *module = PyType_GetModule(defining_class);
13476 self->stat = DirEntry_fetch_stat(module, self, 1);
13477 }
13478 else {
13479 self->stat = DirEntry_get_lstat(defining_class, self);
13480 }
Victor Stinner6036e442015-03-08 01:58:04 +010013481 }
13482
13483 Py_XINCREF(self->stat);
13484 return self->stat;
13485}
13486
Victor Stinner6036e442015-03-08 01:58:04 +010013487/* Set exception and return -1 on error, 0 for False, 1 for True */
13488static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013489DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13490 int follow_symlinks, unsigned short mode_bits)
Victor Stinner6036e442015-03-08 01:58:04 +010013491{
13492 PyObject *stat = NULL;
13493 PyObject *st_mode = NULL;
13494 long mode;
13495 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010013496#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013497 int is_symlink;
13498 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010013499#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013500#ifdef MS_WINDOWS
13501 unsigned long dir_bits;
13502#endif
13503
13504#ifdef MS_WINDOWS
13505 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
13506 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010013507#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013508 is_symlink = self->d_type == DT_LNK;
13509 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
13510#endif
13511
Victor Stinner35a97c02015-03-08 02:59:09 +010013512#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013513 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010013514#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020013515 stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010013516 if (!stat) {
13517 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
13518 /* If file doesn't exist (anymore), then return False
13519 (i.e., say it's not a file/directory) */
13520 PyErr_Clear();
13521 return 0;
13522 }
13523 goto error;
13524 }
Victor Stinner97f33c32020-05-14 18:05:58 +020013525 _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
13526 st_mode = PyObject_GetAttr(stat, state->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010013527 if (!st_mode)
13528 goto error;
13529
13530 mode = PyLong_AsLong(st_mode);
13531 if (mode == -1 && PyErr_Occurred())
13532 goto error;
13533 Py_CLEAR(st_mode);
13534 Py_CLEAR(stat);
13535 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010013536#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013537 }
13538 else if (is_symlink) {
13539 assert(mode_bits != S_IFLNK);
13540 result = 0;
13541 }
13542 else {
13543 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
13544#ifdef MS_WINDOWS
13545 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
13546 if (mode_bits == S_IFDIR)
13547 result = dir_bits != 0;
13548 else
13549 result = dir_bits == 0;
13550#else /* POSIX */
13551 if (mode_bits == S_IFDIR)
13552 result = self->d_type == DT_DIR;
13553 else
13554 result = self->d_type == DT_REG;
13555#endif
13556 }
Victor Stinner35a97c02015-03-08 02:59:09 +010013557#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013558
13559 return result;
13560
13561error:
13562 Py_XDECREF(st_mode);
13563 Py_XDECREF(stat);
13564 return -1;
13565}
13566
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013567/*[clinic input]
13568os.DirEntry.is_dir -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013569 defining_class: defining_class
13570 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013571 *
13572 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010013573
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013574Return True if the entry is a directory; cached per entry.
13575[clinic start generated code]*/
13576
13577static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013578os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
13579 int follow_symlinks)
13580/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013581{
Victor Stinner97f33c32020-05-14 18:05:58 +020013582 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010013583}
13584
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013585/*[clinic input]
13586os.DirEntry.is_file -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013587 defining_class: defining_class
13588 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013589 *
13590 follow_symlinks: bool = True
13591
13592Return True if the entry is a file; cached per entry.
13593[clinic start generated code]*/
13594
13595static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013596os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
13597 int follow_symlinks)
13598/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013599{
Victor Stinner97f33c32020-05-14 18:05:58 +020013600 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010013601}
13602
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013603/*[clinic input]
13604os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010013605
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013606Return inode of the entry; cached per entry.
13607[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013608
13609static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013610os_DirEntry_inode_impl(DirEntry *self)
13611/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013612{
13613#ifdef MS_WINDOWS
13614 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013615 PyObject *unicode;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013616 STRUCT_STAT stat;
13617 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010013618
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013619 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010013620 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013621#if USE_UNICODE_WCHAR_CACHE
13622_Py_COMP_DIAG_PUSH
13623_Py_COMP_DIAG_IGNORE_DEPR_DECLS
13624 const wchar_t *path = PyUnicode_AsUnicode(unicode);
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013625 result = LSTAT(path, &stat);
13626 Py_DECREF(unicode);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013627_Py_COMP_DIAG_POP
13628#else /* USE_UNICODE_WCHAR_CACHE */
13629 wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL);
13630 Py_DECREF(unicode);
13631 result = LSTAT(path, &stat);
13632 PyMem_Free(path);
13633#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013634
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013635 if (result != 0)
13636 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013637
13638 self->win32_file_index = stat.st_ino;
13639 self->got_file_index = 1;
13640 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013641 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13642 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013643#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013644 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13645 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013646#endif
13647}
13648
13649static PyObject *
13650DirEntry_repr(DirEntry *self)
13651{
13652 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13653}
13654
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013655/*[clinic input]
13656os.DirEntry.__fspath__
13657
13658Returns the path for the entry.
13659[clinic start generated code]*/
13660
Brett Cannon96881cd2016-06-10 14:37:21 -070013661static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013662os_DirEntry___fspath___impl(DirEntry *self)
13663/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013664{
13665 Py_INCREF(self->path);
13666 return self->path;
13667}
13668
Victor Stinner6036e442015-03-08 01:58:04 +010013669static PyMemberDef DirEntry_members[] = {
13670 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13671 "the entry's base filename, relative to scandir() \"path\" argument"},
13672 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13673 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13674 {NULL}
13675};
13676
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013677#include "clinic/posixmodule.c.h"
13678
Victor Stinner6036e442015-03-08 01:58:04 +010013679static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013680 OS_DIRENTRY_IS_DIR_METHODDEF
13681 OS_DIRENTRY_IS_FILE_METHODDEF
13682 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13683 OS_DIRENTRY_STAT_METHODDEF
13684 OS_DIRENTRY_INODE_METHODDEF
13685 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013686 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13687 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013688 {NULL}
13689};
13690
Eddie Elizondob3966632019-11-05 07:16:14 -080013691static PyType_Slot DirEntryType_slots[] = {
13692 {Py_tp_new, _disabled_new},
13693 {Py_tp_dealloc, DirEntry_dealloc},
13694 {Py_tp_repr, DirEntry_repr},
13695 {Py_tp_methods, DirEntry_methods},
13696 {Py_tp_members, DirEntry_members},
13697 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013698};
13699
Eddie Elizondob3966632019-11-05 07:16:14 -080013700static PyType_Spec DirEntryType_spec = {
13701 MODNAME ".DirEntry",
13702 sizeof(DirEntry),
13703 0,
13704 Py_TPFLAGS_DEFAULT,
13705 DirEntryType_slots
13706};
13707
13708
Victor Stinner6036e442015-03-08 01:58:04 +010013709#ifdef MS_WINDOWS
13710
13711static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013712join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013713{
13714 Py_ssize_t path_len;
13715 Py_ssize_t size;
13716 wchar_t *result;
13717 wchar_t ch;
13718
13719 if (!path_wide) { /* Default arg: "." */
13720 path_wide = L".";
13721 path_len = 1;
13722 }
13723 else {
13724 path_len = wcslen(path_wide);
13725 }
13726
13727 /* The +1's are for the path separator and the NUL */
13728 size = path_len + 1 + wcslen(filename) + 1;
13729 result = PyMem_New(wchar_t, size);
13730 if (!result) {
13731 PyErr_NoMemory();
13732 return NULL;
13733 }
13734 wcscpy(result, path_wide);
13735 if (path_len > 0) {
13736 ch = result[path_len - 1];
13737 if (ch != SEP && ch != ALTSEP && ch != L':')
13738 result[path_len++] = SEP;
13739 wcscpy(result + path_len, filename);
13740 }
13741 return result;
13742}
13743
13744static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013745DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013746{
13747 DirEntry *entry;
13748 BY_HANDLE_FILE_INFORMATION file_info;
13749 ULONG reparse_tag;
13750 wchar_t *joined_path;
13751
Victor Stinner1c2fa782020-05-10 11:05:29 +020013752 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013753 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013754 if (!entry)
13755 return NULL;
13756 entry->name = NULL;
13757 entry->path = NULL;
13758 entry->stat = NULL;
13759 entry->lstat = NULL;
13760 entry->got_file_index = 0;
13761
13762 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13763 if (!entry->name)
13764 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013765 if (path->narrow) {
13766 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13767 if (!entry->name)
13768 goto error;
13769 }
Victor Stinner6036e442015-03-08 01:58:04 +010013770
13771 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13772 if (!joined_path)
13773 goto error;
13774
13775 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13776 PyMem_Free(joined_path);
13777 if (!entry->path)
13778 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013779 if (path->narrow) {
13780 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13781 if (!entry->path)
13782 goto error;
13783 }
Victor Stinner6036e442015-03-08 01:58:04 +010013784
Steve Dowercc16be82016-09-08 10:35:16 -070013785 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013786 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13787
13788 return (PyObject *)entry;
13789
13790error:
13791 Py_DECREF(entry);
13792 return NULL;
13793}
13794
13795#else /* POSIX */
13796
13797static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013798join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013799{
13800 Py_ssize_t path_len;
13801 Py_ssize_t size;
13802 char *result;
13803
13804 if (!path_narrow) { /* Default arg: "." */
13805 path_narrow = ".";
13806 path_len = 1;
13807 }
13808 else {
13809 path_len = strlen(path_narrow);
13810 }
13811
13812 if (filename_len == -1)
13813 filename_len = strlen(filename);
13814
13815 /* The +1's are for the path separator and the NUL */
13816 size = path_len + 1 + filename_len + 1;
13817 result = PyMem_New(char, size);
13818 if (!result) {
13819 PyErr_NoMemory();
13820 return NULL;
13821 }
13822 strcpy(result, path_narrow);
13823 if (path_len > 0 && result[path_len - 1] != '/')
13824 result[path_len++] = '/';
13825 strcpy(result + path_len, filename);
13826 return result;
13827}
13828
13829static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013830DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13831 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013832#ifdef HAVE_DIRENT_D_TYPE
13833 , unsigned char d_type
13834#endif
13835 )
Victor Stinner6036e442015-03-08 01:58:04 +010013836{
13837 DirEntry *entry;
13838 char *joined_path;
13839
Victor Stinner1c2fa782020-05-10 11:05:29 +020013840 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013841 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013842 if (!entry)
13843 return NULL;
13844 entry->name = NULL;
13845 entry->path = NULL;
13846 entry->stat = NULL;
13847 entry->lstat = NULL;
13848
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013849 if (path->fd != -1) {
13850 entry->dir_fd = path->fd;
13851 joined_path = NULL;
13852 }
13853 else {
13854 entry->dir_fd = DEFAULT_DIR_FD;
13855 joined_path = join_path_filename(path->narrow, name, name_len);
13856 if (!joined_path)
13857 goto error;
13858 }
Victor Stinner6036e442015-03-08 01:58:04 +010013859
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013860 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013861 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013862 if (joined_path)
13863 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013864 }
13865 else {
13866 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013867 if (joined_path)
13868 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013869 }
13870 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013871 if (!entry->name)
13872 goto error;
13873
13874 if (path->fd != -1) {
13875 entry->path = entry->name;
13876 Py_INCREF(entry->path);
13877 }
13878 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013879 goto error;
13880
Victor Stinner35a97c02015-03-08 02:59:09 +010013881#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013882 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013883#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013884 entry->d_ino = d_ino;
13885
13886 return (PyObject *)entry;
13887
13888error:
13889 Py_XDECREF(entry);
13890 return NULL;
13891}
13892
13893#endif
13894
13895
13896typedef struct {
13897 PyObject_HEAD
13898 path_t path;
13899#ifdef MS_WINDOWS
13900 HANDLE handle;
13901 WIN32_FIND_DATAW file_data;
13902 int first_time;
13903#else /* POSIX */
13904 DIR *dirp;
13905#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013906#ifdef HAVE_FDOPENDIR
13907 int fd;
13908#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013909} ScandirIterator;
13910
13911#ifdef MS_WINDOWS
13912
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013913static int
13914ScandirIterator_is_closed(ScandirIterator *iterator)
13915{
13916 return iterator->handle == INVALID_HANDLE_VALUE;
13917}
13918
Victor Stinner6036e442015-03-08 01:58:04 +010013919static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013920ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013921{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013922 HANDLE handle = iterator->handle;
13923
13924 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013925 return;
13926
Victor Stinner6036e442015-03-08 01:58:04 +010013927 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013928 Py_BEGIN_ALLOW_THREADS
13929 FindClose(handle);
13930 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013931}
13932
13933static PyObject *
13934ScandirIterator_iternext(ScandirIterator *iterator)
13935{
13936 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13937 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013938 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013939
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013940 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013941 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013942 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013943
13944 while (1) {
13945 if (!iterator->first_time) {
13946 Py_BEGIN_ALLOW_THREADS
13947 success = FindNextFileW(iterator->handle, file_data);
13948 Py_END_ALLOW_THREADS
13949 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013950 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013951 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013952 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013953 break;
13954 }
13955 }
13956 iterator->first_time = 0;
13957
13958 /* Skip over . and .. */
13959 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020013960 wcscmp(file_data->cFileName, L"..") != 0)
13961 {
13962 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13963 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013964 if (!entry)
13965 break;
13966 return entry;
13967 }
Victor Stinner6036e442015-03-08 01:58:04 +010013968
13969 /* Loop till we get a non-dot directory or finish iterating */
13970 }
13971
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013972 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013973 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013974 return NULL;
13975}
13976
13977#else /* POSIX */
13978
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013979static int
13980ScandirIterator_is_closed(ScandirIterator *iterator)
13981{
13982 return !iterator->dirp;
13983}
13984
Victor Stinner6036e442015-03-08 01:58:04 +010013985static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013986ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013987{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013988 DIR *dirp = iterator->dirp;
13989
13990 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013991 return;
13992
Victor Stinner6036e442015-03-08 01:58:04 +010013993 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013994 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013995#ifdef HAVE_FDOPENDIR
13996 if (iterator->path.fd != -1)
13997 rewinddir(dirp);
13998#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013999 closedir(dirp);
14000 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010014001 return;
14002}
14003
14004static PyObject *
14005ScandirIterator_iternext(ScandirIterator *iterator)
14006{
14007 struct dirent *direntp;
14008 Py_ssize_t name_len;
14009 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014010 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014011
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014012 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014013 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010014014 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014015
14016 while (1) {
14017 errno = 0;
14018 Py_BEGIN_ALLOW_THREADS
14019 direntp = readdir(iterator->dirp);
14020 Py_END_ALLOW_THREADS
14021
14022 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014023 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010014024 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014025 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010014026 break;
14027 }
14028
14029 /* Skip over . and .. */
14030 name_len = NAMLEN(direntp);
14031 is_dot = direntp->d_name[0] == '.' &&
14032 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
14033 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014034 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
14035 entry = DirEntry_from_posix_info(module,
14036 &iterator->path, direntp->d_name,
14037 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010014038#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020014039 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010014040#endif
14041 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014042 if (!entry)
14043 break;
14044 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014045 }
14046
14047 /* Loop till we get a non-dot directory or finish iterating */
14048 }
14049
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014050 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014051 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010014052 return NULL;
14053}
14054
14055#endif
14056
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014057static PyObject *
14058ScandirIterator_close(ScandirIterator *self, PyObject *args)
14059{
14060 ScandirIterator_closedir(self);
14061 Py_RETURN_NONE;
14062}
14063
14064static PyObject *
14065ScandirIterator_enter(PyObject *self, PyObject *args)
14066{
14067 Py_INCREF(self);
14068 return self;
14069}
14070
14071static PyObject *
14072ScandirIterator_exit(ScandirIterator *self, PyObject *args)
14073{
14074 ScandirIterator_closedir(self);
14075 Py_RETURN_NONE;
14076}
14077
Victor Stinner6036e442015-03-08 01:58:04 +010014078static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010014079ScandirIterator_finalize(ScandirIterator *iterator)
14080{
14081 PyObject *error_type, *error_value, *error_traceback;
14082
14083 /* Save the current exception, if any. */
14084 PyErr_Fetch(&error_type, &error_value, &error_traceback);
14085
14086 if (!ScandirIterator_is_closed(iterator)) {
14087 ScandirIterator_closedir(iterator);
14088
14089 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
14090 "unclosed scandir iterator %R", iterator)) {
14091 /* Spurious errors can appear at shutdown */
14092 if (PyErr_ExceptionMatches(PyExc_Warning)) {
14093 PyErr_WriteUnraisable((PyObject *) iterator);
14094 }
14095 }
14096 }
14097
Victor Stinner7bfa4092016-03-23 00:43:54 +010014098 path_cleanup(&iterator->path);
14099
14100 /* Restore the saved exception. */
14101 PyErr_Restore(error_type, error_value, error_traceback);
14102}
14103
14104static void
Victor Stinner6036e442015-03-08 01:58:04 +010014105ScandirIterator_dealloc(ScandirIterator *iterator)
14106{
Eddie Elizondob3966632019-11-05 07:16:14 -080014107 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010014108 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
14109 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014110
Eddie Elizondob3966632019-11-05 07:16:14 -080014111 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
14112 free_func(iterator);
14113 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010014114}
14115
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014116static PyMethodDef ScandirIterator_methods[] = {
14117 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
14118 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
14119 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
14120 {NULL}
14121};
14122
Eddie Elizondob3966632019-11-05 07:16:14 -080014123static PyType_Slot ScandirIteratorType_slots[] = {
14124 {Py_tp_new, _disabled_new},
14125 {Py_tp_dealloc, ScandirIterator_dealloc},
14126 {Py_tp_finalize, ScandirIterator_finalize},
14127 {Py_tp_iter, PyObject_SelfIter},
14128 {Py_tp_iternext, ScandirIterator_iternext},
14129 {Py_tp_methods, ScandirIterator_methods},
14130 {0, 0},
14131};
14132
14133static PyType_Spec ScandirIteratorType_spec = {
14134 MODNAME ".ScandirIterator",
14135 sizeof(ScandirIterator),
14136 0,
Victor Stinner97f33c32020-05-14 18:05:58 +020014137 // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
14138 // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
Eddie Elizondob3966632019-11-05 07:16:14 -080014139 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
14140 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010014141};
14142
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014143/*[clinic input]
14144os.scandir
14145
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014146 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014147
14148Return an iterator of DirEntry objects for given path.
14149
BNMetricsb9427072018-11-02 15:20:19 +000014150path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014151is bytes, the names of yielded DirEntry objects will also be bytes; in
14152all other circumstances they will be str.
14153
14154If path is None, uses the path='.'.
14155[clinic start generated code]*/
14156
Victor Stinner6036e442015-03-08 01:58:04 +010014157static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014158os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000014159/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010014160{
14161 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010014162#ifdef MS_WINDOWS
14163 wchar_t *path_strW;
14164#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014165 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014166#ifdef HAVE_FDOPENDIR
14167 int fd = -1;
14168#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014169#endif
14170
Steve Dower60419a72019-06-24 08:42:54 -070014171 if (PySys_Audit("os.scandir", "O",
14172 path->object ? path->object : Py_None) < 0) {
14173 return NULL;
14174 }
14175
Hai Shif707d942020-03-16 21:15:01 +080014176 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014177 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010014178 if (!iterator)
14179 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014180
14181#ifdef MS_WINDOWS
14182 iterator->handle = INVALID_HANDLE_VALUE;
14183#else
14184 iterator->dirp = NULL;
14185#endif
14186
Serhiy Storchaka095ef732017-02-09 20:05:51 +020014187 /* Move the ownership to iterator->path */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014188 memcpy(&iterator->path, path, sizeof(path_t));
14189 memset(path, 0, sizeof(path_t));
Victor Stinner6036e442015-03-08 01:58:04 +010014190
14191#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010014192 iterator->first_time = 1;
14193
14194 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
14195 if (!path_strW)
14196 goto error;
14197
14198 Py_BEGIN_ALLOW_THREADS
14199 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
14200 Py_END_ALLOW_THREADS
14201
14202 PyMem_Free(path_strW);
14203
14204 if (iterator->handle == INVALID_HANDLE_VALUE) {
14205 path_error(&iterator->path);
14206 goto error;
14207 }
14208#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010014209 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014210#ifdef HAVE_FDOPENDIR
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014211 if (iterator->path.fd != -1) {
Ronald Oussoren41761932020-11-08 10:05:27 +010014212 if (HAVE_FDOPENDIR_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014213 /* closedir() closes the FD, so we duplicate it */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014214 fd = _Py_dup(iterator->path.fd);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014215 if (fd == -1)
14216 goto error;
14217
14218 Py_BEGIN_ALLOW_THREADS
14219 iterator->dirp = fdopendir(fd);
14220 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +010014221 } else {
14222 PyErr_SetString(PyExc_TypeError,
14223 "scandir: path should be string, bytes, os.PathLike or None, not int");
14224 return NULL;
14225 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014226 }
14227 else
14228#endif
14229 {
14230 if (iterator->path.narrow)
14231 path_str = iterator->path.narrow;
14232 else
14233 path_str = ".";
14234
14235 Py_BEGIN_ALLOW_THREADS
14236 iterator->dirp = opendir(path_str);
14237 Py_END_ALLOW_THREADS
14238 }
Victor Stinner6036e442015-03-08 01:58:04 +010014239
14240 if (!iterator->dirp) {
14241 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014242#ifdef HAVE_FDOPENDIR
14243 if (fd != -1) {
14244 Py_BEGIN_ALLOW_THREADS
14245 close(fd);
14246 Py_END_ALLOW_THREADS
14247 }
14248#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014249 goto error;
14250 }
14251#endif
14252
14253 return (PyObject *)iterator;
14254
14255error:
14256 Py_DECREF(iterator);
14257 return NULL;
14258}
14259
Ethan Furman410ef8e2016-06-04 12:06:26 -070014260/*
14261 Return the file system path representation of the object.
14262
14263 If the object is str or bytes, then allow it to pass through with
14264 an incremented refcount. If the object defines __fspath__(), then
14265 return the result of that method. All other types raise a TypeError.
14266*/
14267PyObject *
14268PyOS_FSPath(PyObject *path)
14269{
Brett Cannon3f9183b2016-08-26 14:44:48 -070014270 /* For error message reasons, this function is manually inlined in
14271 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070014272 PyObject *func = NULL;
14273 PyObject *path_repr = NULL;
14274
14275 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
14276 Py_INCREF(path);
14277 return path;
14278 }
14279
14280 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
14281 if (NULL == func) {
14282 return PyErr_Format(PyExc_TypeError,
14283 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014284 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080014285 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070014286 }
14287
Victor Stinnerf17c3de2016-12-06 18:46:19 +010014288 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070014289 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070014290 if (NULL == path_repr) {
14291 return NULL;
14292 }
14293
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014294 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
14295 PyErr_Format(PyExc_TypeError,
14296 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080014297 "not %.200s", _PyType_Name(Py_TYPE(path)),
14298 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014299 Py_DECREF(path_repr);
14300 return NULL;
14301 }
14302
Ethan Furman410ef8e2016-06-04 12:06:26 -070014303 return path_repr;
14304}
14305
14306/*[clinic input]
14307os.fspath
14308
14309 path: object
14310
14311Return the file system path representation of the object.
14312
Brett Cannonb4f43e92016-06-09 14:32:08 -070014313If the object is str or bytes, then allow it to pass through as-is. If the
14314object defines __fspath__(), then return the result of that method. All other
14315types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070014316[clinic start generated code]*/
14317
14318static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030014319os_fspath_impl(PyObject *module, PyObject *path)
14320/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070014321{
14322 return PyOS_FSPath(path);
14323}
Victor Stinner6036e442015-03-08 01:58:04 +010014324
Victor Stinner9b1f4742016-09-06 16:18:52 -070014325#ifdef HAVE_GETRANDOM_SYSCALL
14326/*[clinic input]
14327os.getrandom
14328
14329 size: Py_ssize_t
14330 flags: int=0
14331
14332Obtain a series of random bytes.
14333[clinic start generated code]*/
14334
14335static PyObject *
14336os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
14337/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
14338{
Victor Stinner9b1f4742016-09-06 16:18:52 -070014339 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014340 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014341
14342 if (size < 0) {
14343 errno = EINVAL;
14344 return posix_error();
14345 }
14346
Victor Stinnerec2319c2016-09-20 23:00:59 +020014347 bytes = PyBytes_FromStringAndSize(NULL, size);
14348 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014349 PyErr_NoMemory();
14350 return NULL;
14351 }
14352
14353 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014354 n = syscall(SYS_getrandom,
14355 PyBytes_AS_STRING(bytes),
14356 PyBytes_GET_SIZE(bytes),
14357 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070014358 if (n < 0 && errno == EINTR) {
14359 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014360 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014361 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020014362
14363 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070014364 continue;
14365 }
14366 break;
14367 }
14368
14369 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014370 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020014371 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014372 }
14373
Victor Stinnerec2319c2016-09-20 23:00:59 +020014374 if (n != size) {
14375 _PyBytes_Resize(&bytes, n);
14376 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070014377
14378 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014379
14380error:
14381 Py_DECREF(bytes);
14382 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014383}
14384#endif /* HAVE_GETRANDOM_SYSCALL */
14385
Steve Dower2438cdf2019-03-29 16:37:16 -070014386#ifdef MS_WINDOWS
14387/* bpo-36085: Helper functions for managing DLL search directories
14388 * on win32
14389 */
14390
14391typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
14392typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
14393
14394/*[clinic input]
14395os._add_dll_directory
14396
14397 path: path_t
14398
14399Add a path to the DLL search path.
14400
14401This search path is used when resolving dependencies for imported
14402extension modules (the module itself is resolved through sys.path),
14403and also by ctypes.
14404
14405Returns an opaque value that may be passed to os.remove_dll_directory
14406to remove this directory from the search path.
14407[clinic start generated code]*/
14408
14409static PyObject *
14410os__add_dll_directory_impl(PyObject *module, path_t *path)
14411/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
14412{
14413 HMODULE hKernel32;
14414 PAddDllDirectory AddDllDirectory;
14415 DLL_DIRECTORY_COOKIE cookie = 0;
14416 DWORD err = 0;
14417
Saiyang Gou7514f4f2020-02-12 23:47:42 -080014418 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
14419 return NULL;
14420 }
14421
Steve Dower2438cdf2019-03-29 16:37:16 -070014422 /* For Windows 7, we have to load this. As this will be a fairly
14423 infrequent operation, just do it each time. Kernel32 is always
14424 loaded. */
14425 Py_BEGIN_ALLOW_THREADS
14426 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14427 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
14428 hKernel32, "AddDllDirectory")) ||
14429 !(cookie = (*AddDllDirectory)(path->wide))) {
14430 err = GetLastError();
14431 }
14432 Py_END_ALLOW_THREADS
14433
14434 if (err) {
14435 return win32_error_object_err("add_dll_directory",
14436 path->object, err);
14437 }
14438
14439 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
14440}
14441
14442/*[clinic input]
14443os._remove_dll_directory
14444
14445 cookie: object
14446
14447Removes a path from the DLL search path.
14448
14449The parameter is an opaque value that was returned from
14450os.add_dll_directory. You can only remove directories that you added
14451yourself.
14452[clinic start generated code]*/
14453
14454static PyObject *
14455os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
14456/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
14457{
14458 HMODULE hKernel32;
14459 PRemoveDllDirectory RemoveDllDirectory;
14460 DLL_DIRECTORY_COOKIE cookieValue;
14461 DWORD err = 0;
14462
14463 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
14464 PyErr_SetString(PyExc_TypeError,
14465 "Provided cookie was not returned from os.add_dll_directory");
14466 return NULL;
14467 }
14468
14469 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
14470 cookie, "DLL directory cookie");
14471
14472 /* For Windows 7, we have to load this. As this will be a fairly
14473 infrequent operation, just do it each time. Kernel32 is always
14474 loaded. */
14475 Py_BEGIN_ALLOW_THREADS
14476 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14477 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
14478 hKernel32, "RemoveDllDirectory")) ||
14479 !(*RemoveDllDirectory)(cookieValue)) {
14480 err = GetLastError();
14481 }
14482 Py_END_ALLOW_THREADS
14483
14484 if (err) {
14485 return win32_error_object_err("remove_dll_directory",
14486 NULL, err);
14487 }
14488
14489 if (PyCapsule_SetName(cookie, NULL)) {
14490 return NULL;
14491 }
14492
14493 Py_RETURN_NONE;
14494}
14495
14496#endif
Larry Hastings31826802013-10-19 00:09:25 -070014497
Victor Stinner65a796e2020-04-01 18:49:29 +020014498
14499/* Only check if WIFEXITED is available: expect that it comes
14500 with WEXITSTATUS, WIFSIGNALED, etc.
14501
14502 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
14503 subprocess can safely call it during late Python finalization without
Victor Stinner62230712020-11-18 23:18:29 +010014504 risking that used os attributes were set to None by finalize_modules(). */
Victor Stinner65a796e2020-04-01 18:49:29 +020014505#if defined(WIFEXITED) || defined(MS_WINDOWS)
14506/*[clinic input]
14507os.waitstatus_to_exitcode
14508
Victor Stinner9bee32b2020-04-22 16:30:35 +020014509 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020014510
14511Convert a wait status to an exit code.
14512
14513On Unix:
14514
14515* If WIFEXITED(status) is true, return WEXITSTATUS(status).
14516* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
14517* Otherwise, raise a ValueError.
14518
14519On Windows, return status shifted right by 8 bits.
14520
14521On Unix, if the process is being traced or if waitpid() was called with
14522WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
14523This function must not be called if WIFSTOPPED(status) is true.
14524[clinic start generated code]*/
14525
14526static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020014527os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
14528/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020014529{
14530#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020014531 int status = _PyLong_AsInt(status_obj);
14532 if (status == -1 && PyErr_Occurred()) {
14533 return NULL;
14534 }
14535
Victor Stinner65a796e2020-04-01 18:49:29 +020014536 WAIT_TYPE wait_status;
14537 WAIT_STATUS_INT(wait_status) = status;
14538 int exitcode;
14539 if (WIFEXITED(wait_status)) {
14540 exitcode = WEXITSTATUS(wait_status);
14541 /* Sanity check to provide warranty on the function behavior.
14542 It should not occur in practice */
14543 if (exitcode < 0) {
14544 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
14545 return NULL;
14546 }
14547 }
14548 else if (WIFSIGNALED(wait_status)) {
14549 int signum = WTERMSIG(wait_status);
14550 /* Sanity check to provide warranty on the function behavior.
14551 It should not occurs in practice */
14552 if (signum <= 0) {
14553 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
14554 return NULL;
14555 }
14556 exitcode = -signum;
14557 } else if (WIFSTOPPED(wait_status)) {
14558 /* Status only received if the process is being traced
14559 or if waitpid() was called with WUNTRACED option. */
14560 int signum = WSTOPSIG(wait_status);
14561 PyErr_Format(PyExc_ValueError,
14562 "process stopped by delivery of signal %i",
14563 signum);
14564 return NULL;
14565 }
14566 else {
14567 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
14568 return NULL;
14569 }
14570 return PyLong_FromLong(exitcode);
14571#else
14572 /* Windows implementation: see os.waitpid() implementation
14573 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020014574 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
14575 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
14576 return NULL;
14577 }
14578
14579 unsigned long long exitcode = (status >> 8);
14580 /* ExitProcess() accepts an UINT type:
14581 reject exit code which doesn't fit in an UINT */
14582 if (exitcode > UINT_MAX) {
14583 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
14584 return NULL;
14585 }
14586 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020014587#endif
14588}
14589#endif
14590
14591
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014592static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070014593
14594 OS_STAT_METHODDEF
14595 OS_ACCESS_METHODDEF
14596 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014597 OS_CHDIR_METHODDEF
14598 OS_CHFLAGS_METHODDEF
14599 OS_CHMOD_METHODDEF
14600 OS_FCHMOD_METHODDEF
14601 OS_LCHMOD_METHODDEF
14602 OS_CHOWN_METHODDEF
14603 OS_FCHOWN_METHODDEF
14604 OS_LCHOWN_METHODDEF
14605 OS_LCHFLAGS_METHODDEF
14606 OS_CHROOT_METHODDEF
14607 OS_CTERMID_METHODDEF
14608 OS_GETCWD_METHODDEF
14609 OS_GETCWDB_METHODDEF
14610 OS_LINK_METHODDEF
14611 OS_LISTDIR_METHODDEF
14612 OS_LSTAT_METHODDEF
14613 OS_MKDIR_METHODDEF
14614 OS_NICE_METHODDEF
14615 OS_GETPRIORITY_METHODDEF
14616 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014617 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030014618 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014619 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010014620 OS_COPY_FILE_RANGE_METHODDEF
Pablo Galindoa57b3d32020-11-17 00:00:38 +000014621 OS_SPLICE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014622 OS_RENAME_METHODDEF
14623 OS_REPLACE_METHODDEF
14624 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014625 OS_SYMLINK_METHODDEF
14626 OS_SYSTEM_METHODDEF
14627 OS_UMASK_METHODDEF
14628 OS_UNAME_METHODDEF
14629 OS_UNLINK_METHODDEF
14630 OS_REMOVE_METHODDEF
14631 OS_UTIME_METHODDEF
14632 OS_TIMES_METHODDEF
14633 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014634 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014635 OS_EXECV_METHODDEF
14636 OS_EXECVE_METHODDEF
14637 OS_SPAWNV_METHODDEF
14638 OS_SPAWNVE_METHODDEF
14639 OS_FORK1_METHODDEF
14640 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014641 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014642 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14643 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14644 OS_SCHED_GETPARAM_METHODDEF
14645 OS_SCHED_GETSCHEDULER_METHODDEF
14646 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14647 OS_SCHED_SETPARAM_METHODDEF
14648 OS_SCHED_SETSCHEDULER_METHODDEF
14649 OS_SCHED_YIELD_METHODDEF
14650 OS_SCHED_SETAFFINITY_METHODDEF
14651 OS_SCHED_GETAFFINITY_METHODDEF
14652 OS_OPENPTY_METHODDEF
14653 OS_FORKPTY_METHODDEF
14654 OS_GETEGID_METHODDEF
14655 OS_GETEUID_METHODDEF
14656 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014657 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014658 OS_GETGROUPS_METHODDEF
14659 OS_GETPID_METHODDEF
14660 OS_GETPGRP_METHODDEF
14661 OS_GETPPID_METHODDEF
14662 OS_GETUID_METHODDEF
14663 OS_GETLOGIN_METHODDEF
14664 OS_KILL_METHODDEF
14665 OS_KILLPG_METHODDEF
14666 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014667 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014668 OS_SETUID_METHODDEF
14669 OS_SETEUID_METHODDEF
14670 OS_SETREUID_METHODDEF
14671 OS_SETGID_METHODDEF
14672 OS_SETEGID_METHODDEF
14673 OS_SETREGID_METHODDEF
14674 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014675 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014676 OS_GETPGID_METHODDEF
14677 OS_SETPGRP_METHODDEF
14678 OS_WAIT_METHODDEF
14679 OS_WAIT3_METHODDEF
14680 OS_WAIT4_METHODDEF
14681 OS_WAITID_METHODDEF
14682 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014683 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014684 OS_GETSID_METHODDEF
14685 OS_SETSID_METHODDEF
14686 OS_SETPGID_METHODDEF
14687 OS_TCGETPGRP_METHODDEF
14688 OS_TCSETPGRP_METHODDEF
14689 OS_OPEN_METHODDEF
14690 OS_CLOSE_METHODDEF
14691 OS_CLOSERANGE_METHODDEF
14692 OS_DEVICE_ENCODING_METHODDEF
14693 OS_DUP_METHODDEF
14694 OS_DUP2_METHODDEF
14695 OS_LOCKF_METHODDEF
14696 OS_LSEEK_METHODDEF
14697 OS_READ_METHODDEF
14698 OS_READV_METHODDEF
14699 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014700 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014701 OS_WRITE_METHODDEF
14702 OS_WRITEV_METHODDEF
14703 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014704 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014705 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014706 OS_FSTAT_METHODDEF
14707 OS_ISATTY_METHODDEF
14708 OS_PIPE_METHODDEF
14709 OS_PIPE2_METHODDEF
14710 OS_MKFIFO_METHODDEF
14711 OS_MKNOD_METHODDEF
14712 OS_MAJOR_METHODDEF
14713 OS_MINOR_METHODDEF
14714 OS_MAKEDEV_METHODDEF
14715 OS_FTRUNCATE_METHODDEF
14716 OS_TRUNCATE_METHODDEF
14717 OS_POSIX_FALLOCATE_METHODDEF
14718 OS_POSIX_FADVISE_METHODDEF
14719 OS_PUTENV_METHODDEF
14720 OS_UNSETENV_METHODDEF
14721 OS_STRERROR_METHODDEF
14722 OS_FCHDIR_METHODDEF
14723 OS_FSYNC_METHODDEF
14724 OS_SYNC_METHODDEF
14725 OS_FDATASYNC_METHODDEF
14726 OS_WCOREDUMP_METHODDEF
14727 OS_WIFCONTINUED_METHODDEF
14728 OS_WIFSTOPPED_METHODDEF
14729 OS_WIFSIGNALED_METHODDEF
14730 OS_WIFEXITED_METHODDEF
14731 OS_WEXITSTATUS_METHODDEF
14732 OS_WTERMSIG_METHODDEF
14733 OS_WSTOPSIG_METHODDEF
14734 OS_FSTATVFS_METHODDEF
14735 OS_STATVFS_METHODDEF
14736 OS_CONFSTR_METHODDEF
14737 OS_SYSCONF_METHODDEF
14738 OS_FPATHCONF_METHODDEF
14739 OS_PATHCONF_METHODDEF
14740 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014741 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014742 OS__GETDISKUSAGE_METHODDEF
14743 OS__GETFINALPATHNAME_METHODDEF
14744 OS__GETVOLUMEPATHNAME_METHODDEF
14745 OS_GETLOADAVG_METHODDEF
14746 OS_URANDOM_METHODDEF
14747 OS_SETRESUID_METHODDEF
14748 OS_SETRESGID_METHODDEF
14749 OS_GETRESUID_METHODDEF
14750 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014751
Larry Hastings2f936352014-08-05 14:04:04 +100014752 OS_GETXATTR_METHODDEF
14753 OS_SETXATTR_METHODDEF
14754 OS_REMOVEXATTR_METHODDEF
14755 OS_LISTXATTR_METHODDEF
14756
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014757 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014758 OS_CPU_COUNT_METHODDEF
14759 OS_GET_INHERITABLE_METHODDEF
14760 OS_SET_INHERITABLE_METHODDEF
14761 OS_GET_HANDLE_INHERITABLE_METHODDEF
14762 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014763 OS_GET_BLOCKING_METHODDEF
14764 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014765 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014766 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014767 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014768 OS_MEMFD_CREATE_METHODDEF
Christian Heimescd9fed62020-11-13 19:48:52 +010014769 OS_EVENTFD_METHODDEF
14770 OS_EVENTFD_READ_METHODDEF
14771 OS_EVENTFD_WRITE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014772 OS__ADD_DLL_DIRECTORY_METHODDEF
14773 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014774 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014775 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014776};
14777
Barry Warsaw4a342091996-12-19 23:50:02 +000014778static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014779all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014780{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014781#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014782 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014783#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014784#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014785 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014786#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014787#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014788 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014789#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014790#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014791 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014792#endif
Fred Drakec9680921999-12-13 16:37:25 +000014793#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014794 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014795#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014796#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014797 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014798#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014799#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014800 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014801#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014802#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014803 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014804#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014805#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014806 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014807#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014808#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014809 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014810#endif
14811#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014812 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014813#endif
14814#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014815 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014816#endif
14817#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014818 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014819#endif
14820#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014821 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014822#endif
14823#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014824 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014825#endif
14826#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014827 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014828#endif
14829#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014830 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014831#endif
14832#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014833 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014834#endif
14835#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014836 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014837#endif
14838#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014839 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014840#endif
14841#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014842 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014843#endif
14844#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014845 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014846#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014847#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014848 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014849#endif
14850#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014851 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014852#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014853#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014854 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014855#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014856#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014857 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014858#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014859#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014860#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014861 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014862#endif
14863#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014864 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014865#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014866#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014867#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014868 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014869#endif
14870#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014871 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014872#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014873#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014874 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014875#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014876#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014877 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014878#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014879#ifdef O_TMPFILE
14880 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14881#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014882#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014883 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014884#endif
14885#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014886 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014887#endif
14888#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014889 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014890#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014891#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014892 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014893#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014894#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014895 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014896#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014897
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014898
Jesus Cea94363612012-06-22 18:32:07 +020014899#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014900 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014901#endif
14902#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014903 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014904#endif
14905
Tim Peters5aa91602002-01-30 05:46:57 +000014906/* MS Windows */
14907#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014908 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014909 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014910#endif
14911#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000014912 /* Optimize for short life (keep in memory). */
14913 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014914 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014915#endif
14916#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000014917 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014918 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014919#endif
14920#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000014921 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014922 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014923#endif
14924#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014925 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014926 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014927#endif
14928
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014929/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014930#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014931 /* Send a SIGIO signal whenever input or output
14932 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014933 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014934#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014935#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014936 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014937 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014938#endif
14939#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000014940 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014941 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014942#endif
14943#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000014944 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014945 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014946#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014947#ifdef O_NOLINKS
14948 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014949 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014950#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014951#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014952 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014953 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014954#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000014955
Victor Stinner8c62be82010-05-06 00:08:46 +000014956 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014957#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014958 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014959#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014960#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014961 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014962#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014963#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014964 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014965#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014966#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014967 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014968#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014969#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014970 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014971#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014972#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014973 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014974#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014975#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014976 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014977#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014978#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014979 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014980#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014981#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014982 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014983#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014984#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014985 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014986#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014987#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014988 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014989#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014990#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014991 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014992#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014993#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014994 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014995#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014996#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014997 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014998#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014999#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015000 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015001#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015002#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015003 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015004#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015005#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015006 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015007#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015008
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000015009 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015010#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015011 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015012#endif /* ST_RDONLY */
15013#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015014 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015015#endif /* ST_NOSUID */
15016
doko@ubuntu.comca616a22013-12-08 15:23:07 +010015017 /* GNU extensions */
15018#ifdef ST_NODEV
15019 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
15020#endif /* ST_NODEV */
15021#ifdef ST_NOEXEC
15022 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
15023#endif /* ST_NOEXEC */
15024#ifdef ST_SYNCHRONOUS
15025 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
15026#endif /* ST_SYNCHRONOUS */
15027#ifdef ST_MANDLOCK
15028 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
15029#endif /* ST_MANDLOCK */
15030#ifdef ST_WRITE
15031 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
15032#endif /* ST_WRITE */
15033#ifdef ST_APPEND
15034 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
15035#endif /* ST_APPEND */
15036#ifdef ST_NOATIME
15037 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
15038#endif /* ST_NOATIME */
15039#ifdef ST_NODIRATIME
15040 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
15041#endif /* ST_NODIRATIME */
15042#ifdef ST_RELATIME
15043 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
15044#endif /* ST_RELATIME */
15045
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015046 /* FreeBSD sendfile() constants */
15047#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015048 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015049#endif
15050#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015051 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015052#endif
15053#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015054 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015055#endif
15056
Ross Lagerwall7807c352011-03-17 20:20:30 +020015057 /* constants for posix_fadvise */
15058#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015059 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015060#endif
15061#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015062 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015063#endif
15064#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015065 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015066#endif
15067#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015068 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015069#endif
15070#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015071 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015072#endif
15073#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015074 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015075#endif
15076
15077 /* constants for waitid */
15078#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015079 if (PyModule_AddIntMacro(m, P_PID)) return -1;
15080 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
15081 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080015082#ifdef P_PIDFD
15083 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
15084#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015085#endif
15086#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015087 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015088#endif
15089#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015090 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015091#endif
15092#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015093 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015094#endif
15095#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015096 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015097#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015098#ifdef CLD_KILLED
15099 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
15100#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015101#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015102 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015103#endif
15104#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015105 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015106#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015107#ifdef CLD_STOPPED
15108 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
15109#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015110#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015111 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015112#endif
15113
15114 /* constants for lockf */
15115#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015116 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015117#endif
15118#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015119 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015120#endif
15121#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015122 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015123#endif
15124#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015125 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015126#endif
15127
Pablo Galindo4defba32018-01-27 16:16:37 +000015128#ifdef RWF_DSYNC
15129 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
15130#endif
15131#ifdef RWF_HIPRI
15132 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
15133#endif
15134#ifdef RWF_SYNC
15135 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
15136#endif
15137#ifdef RWF_NOWAIT
15138 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
15139#endif
YoSTEALTH76ef2552020-05-27 15:32:22 -060015140#ifdef RWF_APPEND
15141 if (PyModule_AddIntConstant(m, "RWF_APPEND", RWF_APPEND)) return -1;
15142#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000015143
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015144/* constants for splice */
Pablo Galindo2a9eddf2020-11-17 19:57:49 +000015145#if defined(HAVE_SPLICE) && defined(__linux__)
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015146 if (PyModule_AddIntConstant(m, "SPLICE_F_MOVE", SPLICE_F_MOVE)) return -1;
15147 if (PyModule_AddIntConstant(m, "SPLICE_F_NONBLOCK", SPLICE_F_NONBLOCK)) return -1;
15148 if (PyModule_AddIntConstant(m, "SPLICE_F_MORE", SPLICE_F_MORE)) return -1;
15149#endif
15150
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000015151/* constants for posix_spawn */
15152#ifdef HAVE_POSIX_SPAWN
15153 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
15154 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
15155 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
15156#endif
15157
pxinwrf2d7ac72019-05-21 18:46:37 +080015158#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015159 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
15160 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015161 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080015162#endif
15163#ifdef HAVE_SPAWNV
15164 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015165 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000015166#endif
15167
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015168#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015169#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015170 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015171#endif
15172#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015173 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015174#endif
15175#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015176 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015177#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015178#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080015179 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015180#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015181#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015182 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015183#endif
15184#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015185 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015186#endif
15187#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015188 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015189#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015190#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015191 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015192#endif
15193#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015194 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015195#endif
15196#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015197 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015198#endif
15199#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015200 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015201#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015202#endif
15203
Benjamin Peterson9428d532011-09-14 11:45:52 -040015204#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015205 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
15206 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
15207 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015208#endif
15209
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015210#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015211 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015212#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015213#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015214 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015215#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015216#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015217 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015218#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015219#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015220 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015221#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015222#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015223 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015224#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015225#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015226 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015227#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015228#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015229 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015230#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010015231#if HAVE_DECL_RTLD_MEMBER
15232 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
15233#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020015234
Victor Stinner9b1f4742016-09-06 16:18:52 -070015235#ifdef HAVE_GETRANDOM_SYSCALL
15236 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
15237 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
15238#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015239#ifdef HAVE_MEMFD_CREATE
15240 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
15241 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
15242#ifdef MFD_HUGETLB
15243 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015244#endif
15245#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015246 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015247#endif
15248#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015249 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015250#endif
15251#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015252 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015253#endif
15254#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015255 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015256#endif
15257#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015258 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015259#endif
15260#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015261 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015262#endif
15263#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015264 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015265#endif
15266#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015267 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015268#endif
15269#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015270 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015271#endif
15272#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015273 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015274#endif
15275#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015276 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015277#endif
15278#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015279 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015280#endif
15281#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015282 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015283#endif
15284#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015285 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
15286#endif
Christian Heimescd9fed62020-11-13 19:48:52 +010015287#endif /* HAVE_MEMFD_CREATE */
15288
15289#ifdef HAVE_EVENTFD
15290 if (PyModule_AddIntMacro(m, EFD_CLOEXEC)) return -1;
15291 if (PyModule_AddIntMacro(m, EFD_NONBLOCK)) return -1;
15292 if (PyModule_AddIntMacro(m, EFD_SEMAPHORE)) return -1;
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015293#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070015294
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020015295#if defined(__APPLE__)
15296 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
15297#endif
15298
Steve Dower2438cdf2019-03-29 16:37:16 -070015299#ifdef MS_WINDOWS
15300 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
15301 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
15302 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
15303 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
15304 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
15305#endif
15306
Victor Stinner8c62be82010-05-06 00:08:46 +000015307 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000015308}
15309
15310
Ronald Oussoren41761932020-11-08 10:05:27 +010015311
15312#define PROBE(name, test) \
15313 static int name(void) \
15314 { \
15315 if (test) { \
15316 return 1; \
15317 } else { \
15318 return 0; \
15319 } \
15320 }
15321
15322#ifdef HAVE_FSTATAT
15323PROBE(probe_fstatat, HAVE_FSTATAT_RUNTIME)
15324#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070015325
15326#ifdef HAVE_FACCESSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015327PROBE(probe_faccessat, HAVE_FACCESSAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015328#endif
15329
15330#ifdef HAVE_FCHMODAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015331PROBE(probe_fchmodat, HAVE_FCHMODAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015332#endif
15333
Larry Hastings00964ed2013-08-12 13:49:30 -040015334#ifdef HAVE_FCHOWNAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015335PROBE(probe_fchownat, HAVE_FCHOWNAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015336#endif
15337
15338#ifdef HAVE_LINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015339PROBE(probe_linkat, HAVE_LINKAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015340#endif
15341
Ronald Oussoren41761932020-11-08 10:05:27 +010015342#ifdef HAVE_FDOPENDIR
15343PROBE(probe_fdopendir, HAVE_FDOPENDIR_RUNTIME)
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015344#endif
15345
Larry Hastings9cf065c2012-06-22 16:30:09 -070015346#ifdef HAVE_MKDIRAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015347PROBE(probe_mkdirat, HAVE_MKDIRAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015348#endif
15349
15350#ifdef HAVE_RENAMEAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015351PROBE(probe_renameat, HAVE_RENAMEAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015352#endif
15353
15354#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015355PROBE(probe_unlinkat, HAVE_UNLINKAT_RUNTIME)
15356#endif
15357
15358#ifdef HAVE_OPENAT
15359PROBE(probe_openat, HAVE_OPENAT_RUNTIME)
15360#endif
15361
15362#ifdef HAVE_READLINKAT
15363PROBE(probe_readlinkat, HAVE_READLINKAT_RUNTIME)
15364#endif
15365
15366#ifdef HAVE_SYMLINKAT
15367PROBE(probe_symlinkat, HAVE_SYMLINKAT_RUNTIME)
15368#endif
15369
15370#ifdef HAVE_FUTIMENS
15371PROBE(probe_futimens, HAVE_FUTIMENS_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015372#endif
15373
15374#ifdef HAVE_UTIMENSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015375PROBE(probe_utimensat, HAVE_UTIMENSAT_RUNTIME)
15376#endif
15377
15378
15379
15380
15381static const struct have_function {
15382 const char * const label;
15383 int (*probe)(void);
15384} have_functions[] = {
15385
Christian Heimescd9fed62020-11-13 19:48:52 +010015386#ifdef HAVE_EVENTFD
15387 {"HAVE_EVENTFD", NULL},
15388#endif
15389
Ronald Oussoren41761932020-11-08 10:05:27 +010015390#ifdef HAVE_FACCESSAT
15391 { "HAVE_FACCESSAT", probe_faccessat },
15392#endif
15393
15394#ifdef HAVE_FCHDIR
15395 { "HAVE_FCHDIR", NULL },
15396#endif
15397
15398#ifdef HAVE_FCHMOD
15399 { "HAVE_FCHMOD", NULL },
15400#endif
15401
15402#ifdef HAVE_FCHMODAT
15403 { "HAVE_FCHMODAT", probe_fchmodat },
15404#endif
15405
15406#ifdef HAVE_FCHOWN
15407 { "HAVE_FCHOWN", NULL },
15408#endif
15409
15410#ifdef HAVE_FCHOWNAT
15411 { "HAVE_FCHOWNAT", probe_fchownat },
15412#endif
15413
15414#ifdef HAVE_FEXECVE
15415 { "HAVE_FEXECVE", NULL },
15416#endif
15417
15418#ifdef HAVE_FDOPENDIR
15419 { "HAVE_FDOPENDIR", probe_fdopendir },
15420#endif
15421
15422#ifdef HAVE_FPATHCONF
15423 { "HAVE_FPATHCONF", NULL },
15424#endif
15425
15426#ifdef HAVE_FSTATAT
15427 { "HAVE_FSTATAT", probe_fstatat },
15428#endif
15429
15430#ifdef HAVE_FSTATVFS
15431 { "HAVE_FSTATVFS", NULL },
15432#endif
15433
15434#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
15435 { "HAVE_FTRUNCATE", NULL },
15436#endif
15437
15438#ifdef HAVE_FUTIMENS
15439 { "HAVE_FUTIMENS", probe_futimens },
15440#endif
15441
15442#ifdef HAVE_FUTIMES
15443 { "HAVE_FUTIMES", NULL },
15444#endif
15445
15446#ifdef HAVE_FUTIMESAT
15447 { "HAVE_FUTIMESAT", NULL },
15448#endif
15449
15450#ifdef HAVE_LINKAT
15451 { "HAVE_LINKAT", probe_linkat },
15452#endif
15453
15454#ifdef HAVE_LCHFLAGS
15455 { "HAVE_LCHFLAGS", NULL },
15456#endif
15457
15458#ifdef HAVE_LCHMOD
15459 { "HAVE_LCHMOD", NULL },
15460#endif
15461
15462#ifdef HAVE_LCHOWN
15463 { "HAVE_LCHOWN", NULL },
15464#endif
15465
15466#ifdef HAVE_LSTAT
15467 { "HAVE_LSTAT", NULL },
15468#endif
15469
15470#ifdef HAVE_LUTIMES
15471 { "HAVE_LUTIMES", NULL },
15472#endif
15473
15474#ifdef HAVE_MEMFD_CREATE
15475 { "HAVE_MEMFD_CREATE", NULL },
15476#endif
15477
15478#ifdef HAVE_MKDIRAT
15479 { "HAVE_MKDIRAT", probe_mkdirat },
15480#endif
15481
15482#ifdef HAVE_MKFIFOAT
15483 { "HAVE_MKFIFOAT", NULL },
15484#endif
15485
15486#ifdef HAVE_MKNODAT
15487 { "HAVE_MKNODAT", NULL },
15488#endif
15489
15490#ifdef HAVE_OPENAT
15491 { "HAVE_OPENAT", probe_openat },
15492#endif
15493
15494#ifdef HAVE_READLINKAT
15495 { "HAVE_READLINKAT", probe_readlinkat },
15496#endif
15497
15498#ifdef HAVE_RENAMEAT
15499 { "HAVE_RENAMEAT", probe_renameat },
15500#endif
15501
15502#ifdef HAVE_SYMLINKAT
15503 { "HAVE_SYMLINKAT", probe_symlinkat },
15504#endif
15505
15506#ifdef HAVE_UNLINKAT
15507 { "HAVE_UNLINKAT", probe_unlinkat },
15508#endif
15509
15510#ifdef HAVE_UTIMENSAT
15511 { "HAVE_UTIMENSAT", probe_utimensat },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015512#endif
15513
15514#ifdef MS_WINDOWS
Ronald Oussoren41761932020-11-08 10:05:27 +010015515 { "MS_WINDOWS", NULL },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015516#endif
15517
Ronald Oussoren41761932020-11-08 10:05:27 +010015518 { NULL, NULL }
Larry Hastings9cf065c2012-06-22 16:30:09 -070015519};
15520
15521
Victor Stinner1c2fa782020-05-10 11:05:29 +020015522static int
15523posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000015524{
Victor Stinner97f33c32020-05-14 18:05:58 +020015525 _posixstate *state = get_posix_state(m);
Tim Peters5aa91602002-01-30 05:46:57 +000015526
Ronald Oussoren41761932020-11-08 10:05:27 +010015527#if defined(HAVE_PWRITEV)
15528 if (HAVE_PWRITEV_RUNTIME) {} else {
15529 PyObject* dct = PyModule_GetDict(m);
15530
15531 if (dct == NULL) {
15532 return -1;
15533 }
15534
15535 if (PyDict_DelItemString(dct, "pwritev") == -1) {
15536 PyErr_Clear();
15537 }
15538 if (PyDict_DelItemString(dct, "preadv") == -1) {
15539 PyErr_Clear();
15540 }
15541 }
15542#endif
15543
Victor Stinner8c62be82010-05-06 00:08:46 +000015544 /* Initialize environ dictionary */
Victor Stinner97f33c32020-05-14 18:05:58 +020015545 PyObject *v = convertenviron();
Victor Stinner8c62be82010-05-06 00:08:46 +000015546 Py_XINCREF(v);
15547 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015548 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015549 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000015550
Victor Stinner8c62be82010-05-06 00:08:46 +000015551 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015552 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000015553
Victor Stinner8c62be82010-05-06 00:08:46 +000015554 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015555 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000015556
Victor Stinner8c62be82010-05-06 00:08:46 +000015557 Py_INCREF(PyExc_OSError);
15558 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000015559
Ross Lagerwall7807c352011-03-17 20:20:30 +020015560#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080015561 waitid_result_desc.name = MODNAME ".waitid_result";
15562 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
15563 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015564 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015565 }
15566 Py_INCREF(WaitidResultType);
15567 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015568 state->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015569#endif
15570
Eddie Elizondob3966632019-11-05 07:16:14 -080015571 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
15572 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
15573 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
15574 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
15575 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
15576 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015577 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015578 }
15579 Py_INCREF(StatResultType);
15580 PyModule_AddObject(m, "stat_result", StatResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015581 state->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015582 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
15583 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015584
Eddie Elizondob3966632019-11-05 07:16:14 -080015585 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
15586 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
15587 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015588 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015589 }
15590 Py_INCREF(StatVFSResultType);
15591 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015592 state->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015593#ifdef NEED_TICKS_PER_SECOND
15594# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080015595 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015596# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080015597 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015598# else
Eddie Elizondob3966632019-11-05 07:16:14 -080015599 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015600# endif
15601#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015602
William Orr81574b82018-10-01 22:19:56 -070015603#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080015604 sched_param_desc.name = MODNAME ".sched_param";
15605 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
15606 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015607 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015608 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015609 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080015610 PyModule_AddObject(m, "sched_param", SchedParamType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015611 state->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015612 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050015613#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000015614
Eddie Elizondob3966632019-11-05 07:16:14 -080015615 /* initialize TerminalSize_info */
15616 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
15617 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015618 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015619 }
15620 Py_INCREF(TerminalSizeType);
15621 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015622 state->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015623
15624 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020015625 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015626 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015627 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015628 }
Victor Stinner97f33c32020-05-14 18:05:58 +020015629 state->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015630
Victor Stinner1c2fa782020-05-10 11:05:29 +020015631 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015632 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015633 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015634 }
15635 Py_INCREF(DirEntryType);
15636 PyModule_AddObject(m, "DirEntry", DirEntryType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015637 state->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015638
Larry Hastings605a62d2012-06-24 04:33:36 -070015639 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080015640 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015641 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015642 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015643 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015644 Py_INCREF(TimesResultType);
15645 PyModule_AddObject(m, "times_result", TimesResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015646 state->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015647
Eddie Elizondob3966632019-11-05 07:16:14 -080015648 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015649 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015650 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015651 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015652 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015653 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015654 state->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015655
Victor Stinner97f33c32020-05-14 18:05:58 +020015656 if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015657 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015658#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +020015659 state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
15660 if (state->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015661 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015662#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020015663 state->st_mode = PyUnicode_InternFromString("st_mode");
15664 if (state->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015665 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070015666
Larry Hastings9cf065c2012-06-22 16:30:09 -070015667 /* suppress "function not used" warnings */
15668 {
15669 int ignored;
15670 fd_specified("", -1);
15671 follow_symlinks_specified("", 1);
15672 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
15673 dir_fd_converter(Py_None, &ignored);
15674 dir_fd_unavailable(Py_None, &ignored);
15675 }
15676
15677 /*
15678 * provide list of locally available functions
15679 * so os.py can populate support_* lists
15680 */
Victor Stinner97f33c32020-05-14 18:05:58 +020015681 PyObject *list = PyList_New(0);
15682 if (!list) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015683 return -1;
Victor Stinner97f33c32020-05-14 18:05:58 +020015684 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015685 for (const struct have_function *trace = have_functions; trace->label; trace++) {
15686 PyObject *unicode;
15687 if (trace->probe && !trace->probe()) continue;
15688 unicode = PyUnicode_DecodeASCII(trace->label, strlen(trace->label), NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015689 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015690 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015691 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015692 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015693 Py_DECREF(unicode);
15694 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015695
Larry Hastings9cf065c2012-06-22 16:30:09 -070015696 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040015697
Victor Stinner1c2fa782020-05-10 11:05:29 +020015698 return 0;
15699}
15700
15701
15702static PyModuleDef_Slot posixmodile_slots[] = {
15703 {Py_mod_exec, posixmodule_exec},
15704 {0, NULL}
15705};
15706
15707static struct PyModuleDef posixmodule = {
15708 PyModuleDef_HEAD_INIT,
15709 .m_name = MODNAME,
15710 .m_doc = posix__doc__,
15711 .m_size = sizeof(_posixstate),
15712 .m_methods = posix_methods,
15713 .m_slots = posixmodile_slots,
15714 .m_traverse = _posix_traverse,
15715 .m_clear = _posix_clear,
15716 .m_free = _posix_free,
15717};
15718
15719PyMODINIT_FUNC
15720INITFUNC(void)
15721{
15722 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015723}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015724
15725#ifdef __cplusplus
15726}
15727#endif