blob: d9eb62f20e65bd706f4e11ef37184c5ba7ace2c1 [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]);
Victor Stinner00d7abd2020-12-01 09:56:42 +01005483 PyMem_Free(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 Stinner00d7abd2020-12-01 09:56:42 +01006513 while (--envc >= 0) {
6514 PyMem_Free(envlist[envc]);
6515 }
6516 PyMem_Free(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006517 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006518 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006519 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006521}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006522
Guido van Rossuma1065681999-01-25 23:20:23 +00006523#endif /* HAVE_SPAWNV */
6524
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006525#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006526
6527/* Helper function to validate arguments.
6528 Returns 0 on success. non-zero on failure with a TypeError raised.
6529 If obj is non-NULL it must be callable. */
6530static int
6531check_null_or_callable(PyObject *obj, const char* obj_name)
6532{
6533 if (obj && !PyCallable_Check(obj)) {
6534 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006535 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006536 return -1;
6537 }
6538 return 0;
6539}
6540
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006541/*[clinic input]
6542os.register_at_fork
6543
Gregory P. Smith163468a2017-05-29 10:03:41 -07006544 *
6545 before: object=NULL
6546 A callable to be called in the parent before the fork() syscall.
6547 after_in_child: object=NULL
6548 A callable to be called in the child after fork().
6549 after_in_parent: object=NULL
6550 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006551
Gregory P. Smith163468a2017-05-29 10:03:41 -07006552Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006553
Gregory P. Smith163468a2017-05-29 10:03:41 -07006554'before' callbacks are called in reverse order.
6555'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006556
6557[clinic start generated code]*/
6558
6559static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006560os_register_at_fork_impl(PyObject *module, PyObject *before,
6561 PyObject *after_in_child, PyObject *after_in_parent)
6562/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006563{
6564 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006565
Gregory P. Smith163468a2017-05-29 10:03:41 -07006566 if (!before && !after_in_child && !after_in_parent) {
6567 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6568 return NULL;
6569 }
6570 if (check_null_or_callable(before, "before") ||
6571 check_null_or_callable(after_in_child, "after_in_child") ||
6572 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006573 return NULL;
6574 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006575 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006576
Gregory P. Smith163468a2017-05-29 10:03:41 -07006577 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006578 return NULL;
6579 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006580 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006581 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006582 }
6583 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6584 return NULL;
6585 }
6586 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006587}
6588#endif /* HAVE_FORK */
6589
6590
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006591#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006592/*[clinic input]
6593os.fork1
6594
6595Fork a child process with a single multiplexed (i.e., not bound) thread.
6596
6597Return 0 to child process and PID of child to parent process.
6598[clinic start generated code]*/
6599
Larry Hastings2f936352014-08-05 14:04:04 +10006600static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006601os_fork1_impl(PyObject *module)
6602/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006603{
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006605
Victor Stinner81a7be32020-04-14 15:14:01 +02006606 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006607 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6608 return NULL;
6609 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006610 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 pid = fork1();
6612 if (pid == 0) {
6613 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006614 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006615 } else {
6616 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006617 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006618 }
6619 if (pid == -1)
6620 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006621 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006622}
Larry Hastings2f936352014-08-05 14:04:04 +10006623#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006624
6625
Guido van Rossumad0ee831995-03-01 10:34:45 +00006626#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006627/*[clinic input]
6628os.fork
6629
6630Fork a child process.
6631
6632Return 0 to child process and PID of child to parent process.
6633[clinic start generated code]*/
6634
Larry Hastings2f936352014-08-05 14:04:04 +10006635static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006636os_fork_impl(PyObject *module)
6637/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006638{
Victor Stinner8c62be82010-05-06 00:08:46 +00006639 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006640 PyInterpreterState *interp = _PyInterpreterState_GET();
6641 if (interp->config._isolated_interpreter) {
6642 PyErr_SetString(PyExc_RuntimeError,
6643 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006644 return NULL;
6645 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006646 if (PySys_Audit("os.fork", NULL) < 0) {
6647 return NULL;
6648 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006649 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 pid = fork();
6651 if (pid == 0) {
6652 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006653 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 } else {
6655 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006656 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006657 }
6658 if (pid == -1)
6659 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006660 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006661}
Larry Hastings2f936352014-08-05 14:04:04 +10006662#endif /* HAVE_FORK */
6663
Guido van Rossum85e3b011991-06-03 12:42:10 +00006664
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006665#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006666#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006667/*[clinic input]
6668os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006669
Larry Hastings2f936352014-08-05 14:04:04 +10006670 policy: int
6671
6672Get the maximum scheduling priority for policy.
6673[clinic start generated code]*/
6674
Larry Hastings2f936352014-08-05 14:04:04 +10006675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006676os_sched_get_priority_max_impl(PyObject *module, int policy)
6677/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006678{
6679 int max;
6680
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006681 max = sched_get_priority_max(policy);
6682 if (max < 0)
6683 return posix_error();
6684 return PyLong_FromLong(max);
6685}
6686
Larry Hastings2f936352014-08-05 14:04:04 +10006687
6688/*[clinic input]
6689os.sched_get_priority_min
6690
6691 policy: int
6692
6693Get the minimum scheduling priority for policy.
6694[clinic start generated code]*/
6695
Larry Hastings2f936352014-08-05 14:04:04 +10006696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006697os_sched_get_priority_min_impl(PyObject *module, int policy)
6698/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006699{
6700 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006701 if (min < 0)
6702 return posix_error();
6703 return PyLong_FromLong(min);
6704}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006705#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6706
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006707
Larry Hastings2f936352014-08-05 14:04:04 +10006708#ifdef HAVE_SCHED_SETSCHEDULER
6709/*[clinic input]
6710os.sched_getscheduler
6711 pid: pid_t
6712 /
6713
Min ho Kimc4cacc82019-07-31 08:16:13 +10006714Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006715
6716Passing 0 for pid returns the scheduling policy for the calling process.
6717[clinic start generated code]*/
6718
Larry Hastings2f936352014-08-05 14:04:04 +10006719static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006720os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006721/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006722{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006723 int policy;
6724
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006725 policy = sched_getscheduler(pid);
6726 if (policy < 0)
6727 return posix_error();
6728 return PyLong_FromLong(policy);
6729}
Larry Hastings2f936352014-08-05 14:04:04 +10006730#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006731
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006732
William Orr81574b82018-10-01 22:19:56 -07006733#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006734/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006735class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006736
6737@classmethod
6738os.sched_param.__new__
6739
6740 sched_priority: object
6741 A scheduling parameter.
6742
Eddie Elizondob3966632019-11-05 07:16:14 -08006743Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006744[clinic start generated code]*/
6745
Larry Hastings2f936352014-08-05 14:04:04 +10006746static PyObject *
6747os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006748/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006749{
6750 PyObject *res;
6751
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006752 res = PyStructSequence_New(type);
6753 if (!res)
6754 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006755 Py_INCREF(sched_priority);
6756 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006757 return res;
6758}
6759
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006760PyDoc_VAR(os_sched_param__doc__);
6761
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006762static PyStructSequence_Field sched_param_fields[] = {
6763 {"sched_priority", "the scheduling priority"},
6764 {0}
6765};
6766
6767static PyStructSequence_Desc sched_param_desc = {
6768 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006769 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006770 sched_param_fields,
6771 1
6772};
6773
6774static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006775convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006776{
6777 long priority;
6778
Victor Stinner1c2fa782020-05-10 11:05:29 +02006779 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006780 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6781 return 0;
6782 }
6783 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6784 if (priority == -1 && PyErr_Occurred())
6785 return 0;
6786 if (priority > INT_MAX || priority < INT_MIN) {
6787 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6788 return 0;
6789 }
6790 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6791 return 1;
6792}
William Orr81574b82018-10-01 22:19:56 -07006793#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006794
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006795
6796#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006797/*[clinic input]
6798os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006799
Larry Hastings2f936352014-08-05 14:04:04 +10006800 pid: pid_t
6801 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006802 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006803 /
6804
6805Set the scheduling policy for the process identified by pid.
6806
6807If pid is 0, the calling process is changed.
6808param is an instance of sched_param.
6809[clinic start generated code]*/
6810
Larry Hastings2f936352014-08-05 14:04:04 +10006811static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006812os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006813 PyObject *param_obj)
6814/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006815{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006816 struct sched_param param;
6817 if (!convert_sched_param(module, param_obj, &param)) {
6818 return NULL;
6819 }
6820
Jesus Cea9c822272011-09-10 01:40:52 +02006821 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006822 ** sched_setscheduler() returns 0 in Linux, but the previous
6823 ** scheduling policy under Solaris/Illumos, and others.
6824 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006825 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006826 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006827 return posix_error();
6828 Py_RETURN_NONE;
6829}
Larry Hastings2f936352014-08-05 14:04:04 +10006830#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006831
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006832
6833#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006834/*[clinic input]
6835os.sched_getparam
6836 pid: pid_t
6837 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006838
Larry Hastings2f936352014-08-05 14:04:04 +10006839Returns scheduling parameters for the process identified by pid.
6840
6841If pid is 0, returns parameters for the calling process.
6842Return value is an instance of sched_param.
6843[clinic start generated code]*/
6844
Larry Hastings2f936352014-08-05 14:04:04 +10006845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006846os_sched_getparam_impl(PyObject *module, pid_t pid)
6847/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006848{
6849 struct sched_param param;
6850 PyObject *result;
6851 PyObject *priority;
6852
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006853 if (sched_getparam(pid, &param))
6854 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006855 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006856 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006857 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006858 return NULL;
6859 priority = PyLong_FromLong(param.sched_priority);
6860 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006861 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006862 return NULL;
6863 }
Larry Hastings2f936352014-08-05 14:04:04 +10006864 PyStructSequence_SET_ITEM(result, 0, priority);
6865 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006866}
6867
Larry Hastings2f936352014-08-05 14:04:04 +10006868
6869/*[clinic input]
6870os.sched_setparam
6871 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006872 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006873 /
6874
6875Set scheduling parameters for the process identified by pid.
6876
6877If pid is 0, sets parameters for the calling process.
6878param should be an instance of sched_param.
6879[clinic start generated code]*/
6880
Larry Hastings2f936352014-08-05 14:04:04 +10006881static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006882os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6883/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006884{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006885 struct sched_param param;
6886 if (!convert_sched_param(module, param_obj, &param)) {
6887 return NULL;
6888 }
6889
6890 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006891 return posix_error();
6892 Py_RETURN_NONE;
6893}
Larry Hastings2f936352014-08-05 14:04:04 +10006894#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006895
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006896
6897#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006898/*[clinic input]
6899os.sched_rr_get_interval -> double
6900 pid: pid_t
6901 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006902
Larry Hastings2f936352014-08-05 14:04:04 +10006903Return the round-robin quantum for the process identified by pid, in seconds.
6904
6905Value returned is a float.
6906[clinic start generated code]*/
6907
Larry Hastings2f936352014-08-05 14:04:04 +10006908static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006909os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6910/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006911{
6912 struct timespec interval;
6913 if (sched_rr_get_interval(pid, &interval)) {
6914 posix_error();
6915 return -1.0;
6916 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006917#ifdef _Py_MEMORY_SANITIZER
6918 __msan_unpoison(&interval, sizeof(interval));
6919#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006920 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6921}
6922#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006923
Larry Hastings2f936352014-08-05 14:04:04 +10006924
6925/*[clinic input]
6926os.sched_yield
6927
6928Voluntarily relinquish the CPU.
6929[clinic start generated code]*/
6930
Larry Hastings2f936352014-08-05 14:04:04 +10006931static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006932os_sched_yield_impl(PyObject *module)
6933/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006934{
6935 if (sched_yield())
6936 return posix_error();
6937 Py_RETURN_NONE;
6938}
6939
Benjamin Peterson2740af82011-08-02 17:41:34 -05006940#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006941/* The minimum number of CPUs allocated in a cpu_set_t */
6942static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006943
Larry Hastings2f936352014-08-05 14:04:04 +10006944/*[clinic input]
6945os.sched_setaffinity
6946 pid: pid_t
6947 mask : object
6948 /
6949
6950Set the CPU affinity of the process identified by pid to mask.
6951
6952mask should be an iterable of integers identifying CPUs.
6953[clinic start generated code]*/
6954
Larry Hastings2f936352014-08-05 14:04:04 +10006955static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006956os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6957/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006958{
Antoine Pitrou84869872012-08-04 16:16:35 +02006959 int ncpus;
6960 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006961 cpu_set_t *cpu_set = NULL;
6962 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006963
Larry Hastings2f936352014-08-05 14:04:04 +10006964 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006965 if (iterator == NULL)
6966 return NULL;
6967
6968 ncpus = NCPUS_START;
6969 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006970 cpu_set = CPU_ALLOC(ncpus);
6971 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006972 PyErr_NoMemory();
6973 goto error;
6974 }
Larry Hastings2f936352014-08-05 14:04:04 +10006975 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006976
6977 while ((item = PyIter_Next(iterator))) {
6978 long cpu;
6979 if (!PyLong_Check(item)) {
6980 PyErr_Format(PyExc_TypeError,
6981 "expected an iterator of ints, "
6982 "but iterator yielded %R",
6983 Py_TYPE(item));
6984 Py_DECREF(item);
6985 goto error;
6986 }
6987 cpu = PyLong_AsLong(item);
6988 Py_DECREF(item);
6989 if (cpu < 0) {
6990 if (!PyErr_Occurred())
6991 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6992 goto error;
6993 }
6994 if (cpu > INT_MAX - 1) {
6995 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
6996 goto error;
6997 }
6998 if (cpu >= ncpus) {
6999 /* Grow CPU mask to fit the CPU number */
7000 int newncpus = ncpus;
7001 cpu_set_t *newmask;
7002 size_t newsetsize;
7003 while (newncpus <= cpu) {
7004 if (newncpus > INT_MAX / 2)
7005 newncpus = cpu + 1;
7006 else
7007 newncpus = newncpus * 2;
7008 }
7009 newmask = CPU_ALLOC(newncpus);
7010 if (newmask == NULL) {
7011 PyErr_NoMemory();
7012 goto error;
7013 }
7014 newsetsize = CPU_ALLOC_SIZE(newncpus);
7015 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10007016 memcpy(newmask, cpu_set, setsize);
7017 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007018 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007019 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02007020 ncpus = newncpus;
7021 }
Larry Hastings2f936352014-08-05 14:04:04 +10007022 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007023 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07007024 if (PyErr_Occurred()) {
7025 goto error;
7026 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007027 Py_CLEAR(iterator);
7028
Larry Hastings2f936352014-08-05 14:04:04 +10007029 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007030 posix_error();
7031 goto error;
7032 }
Larry Hastings2f936352014-08-05 14:04:04 +10007033 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007034 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02007035
7036error:
Larry Hastings2f936352014-08-05 14:04:04 +10007037 if (cpu_set)
7038 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007039 Py_XDECREF(iterator);
7040 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007041}
7042
Larry Hastings2f936352014-08-05 14:04:04 +10007043
7044/*[clinic input]
7045os.sched_getaffinity
7046 pid: pid_t
7047 /
7048
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01007049Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10007050
7051The affinity is returned as a set of CPU identifiers.
7052[clinic start generated code]*/
7053
Larry Hastings2f936352014-08-05 14:04:04 +10007054static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007055os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03007056/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007057{
Antoine Pitrou84869872012-08-04 16:16:35 +02007058 int cpu, ncpus, count;
7059 size_t setsize;
7060 cpu_set_t *mask = NULL;
7061 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007062
Antoine Pitrou84869872012-08-04 16:16:35 +02007063 ncpus = NCPUS_START;
7064 while (1) {
7065 setsize = CPU_ALLOC_SIZE(ncpus);
7066 mask = CPU_ALLOC(ncpus);
7067 if (mask == NULL)
7068 return PyErr_NoMemory();
7069 if (sched_getaffinity(pid, setsize, mask) == 0)
7070 break;
7071 CPU_FREE(mask);
7072 if (errno != EINVAL)
7073 return posix_error();
7074 if (ncpus > INT_MAX / 2) {
7075 PyErr_SetString(PyExc_OverflowError, "could not allocate "
7076 "a large enough CPU set");
7077 return NULL;
7078 }
7079 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007080 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007081
7082 res = PySet_New(NULL);
7083 if (res == NULL)
7084 goto error;
7085 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
7086 if (CPU_ISSET_S(cpu, setsize, mask)) {
7087 PyObject *cpu_num = PyLong_FromLong(cpu);
7088 --count;
7089 if (cpu_num == NULL)
7090 goto error;
7091 if (PySet_Add(res, cpu_num)) {
7092 Py_DECREF(cpu_num);
7093 goto error;
7094 }
7095 Py_DECREF(cpu_num);
7096 }
7097 }
7098 CPU_FREE(mask);
7099 return res;
7100
7101error:
7102 if (mask)
7103 CPU_FREE(mask);
7104 Py_XDECREF(res);
7105 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007106}
7107
Benjamin Peterson2740af82011-08-02 17:41:34 -05007108#endif /* HAVE_SCHED_SETAFFINITY */
7109
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007110#endif /* HAVE_SCHED_H */
7111
Larry Hastings2f936352014-08-05 14:04:04 +10007112
Neal Norwitzb59798b2003-03-21 01:43:31 +00007113/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00007114#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Victor Stinner57766632020-10-29 15:16:23 +01007115# define DEV_PTY_FILE "/dev/ptc"
7116# define HAVE_DEV_PTMX
Neal Norwitzb59798b2003-03-21 01:43:31 +00007117#else
Victor Stinner57766632020-10-29 15:16:23 +01007118# define DEV_PTY_FILE "/dev/ptmx"
Neal Norwitzb59798b2003-03-21 01:43:31 +00007119#endif
7120
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007121#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00007122#ifdef HAVE_PTY_H
7123#include <pty.h>
7124#else
7125#ifdef HAVE_LIBUTIL_H
7126#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00007127#else
7128#ifdef HAVE_UTIL_H
7129#include <util.h>
7130#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007131#endif /* HAVE_LIBUTIL_H */
7132#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00007133#ifdef HAVE_STROPTS_H
7134#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007135#endif
ngie-eign7745ec42018-02-14 11:54:28 -08007136#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007137
Larry Hastings2f936352014-08-05 14:04:04 +10007138
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007139#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10007140/*[clinic input]
7141os.openpty
7142
7143Open a pseudo-terminal.
7144
7145Return a tuple of (master_fd, slave_fd) containing open file descriptors
7146for both the master and slave ends.
7147[clinic start generated code]*/
7148
Larry Hastings2f936352014-08-05 14:04:04 +10007149static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007150os_openpty_impl(PyObject *module)
7151/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007152{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007153 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007154#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007155 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007156#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007157#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007158 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01007159#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00007160 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007161#endif
7162#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00007163
Thomas Wouters70c21a12000-07-14 14:28:33 +00007164#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007166 goto posix_error;
7167
7168 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7169 goto error;
7170 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
7171 goto error;
7172
Neal Norwitzb59798b2003-03-21 01:43:31 +00007173#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
7175 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007176 goto posix_error;
7177 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7178 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007179
Victor Stinnerdaf45552013-08-28 00:53:59 +02007180 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00007181 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01007182 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007183
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007184#else
Victor Stinner000de532013-11-25 23:19:58 +01007185 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00007186 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007187 goto posix_error;
7188
Victor Stinner8c62be82010-05-06 00:08:46 +00007189 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007190
Victor Stinner8c62be82010-05-06 00:08:46 +00007191 /* change permission of slave */
7192 if (grantpt(master_fd) < 0) {
7193 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007194 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007196
Victor Stinner8c62be82010-05-06 00:08:46 +00007197 /* unlock slave */
7198 if (unlockpt(master_fd) < 0) {
7199 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007200 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007201 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007202
Victor Stinner8c62be82010-05-06 00:08:46 +00007203 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007204
Victor Stinner8c62be82010-05-06 00:08:46 +00007205 slave_name = ptsname(master_fd); /* get name of slave */
7206 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007207 goto posix_error;
7208
7209 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01007210 if (slave_fd == -1)
7211 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01007212
7213 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7214 goto posix_error;
7215
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02007216#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00007217 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
7218 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00007219#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00007220 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00007221#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007222#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00007223#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00007224
Victor Stinner8c62be82010-05-06 00:08:46 +00007225 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00007226
Victor Stinnerdaf45552013-08-28 00:53:59 +02007227posix_error:
7228 posix_error();
7229error:
7230 if (master_fd != -1)
7231 close(master_fd);
7232 if (slave_fd != -1)
7233 close(slave_fd);
7234 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00007235}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007236#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007237
Larry Hastings2f936352014-08-05 14:04:04 +10007238
Fred Drake8cef4cf2000-06-28 16:40:38 +00007239#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10007240/*[clinic input]
7241os.forkpty
7242
7243Fork a new process with a new pseudo-terminal as controlling tty.
7244
7245Returns a tuple of (pid, master_fd).
7246Like fork(), return pid of 0 to the child process,
7247and pid of child to the parent process.
7248To both, return fd of newly opened pseudo-terminal.
7249[clinic start generated code]*/
7250
Larry Hastings2f936352014-08-05 14:04:04 +10007251static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007252os_forkpty_impl(PyObject *module)
7253/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007254{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007255 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00007256 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00007257
Victor Stinner81a7be32020-04-14 15:14:01 +02007258 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07007259 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
7260 return NULL;
7261 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007262 if (PySys_Audit("os.forkpty", NULL) < 0) {
7263 return NULL;
7264 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007265 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00007266 pid = forkpty(&master_fd, NULL, NULL, NULL);
7267 if (pid == 0) {
7268 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007269 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00007270 } else {
7271 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007272 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00007273 }
7274 if (pid == -1)
7275 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007276 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00007277}
Larry Hastings2f936352014-08-05 14:04:04 +10007278#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007279
Ross Lagerwall7807c352011-03-17 20:20:30 +02007280
Guido van Rossumad0ee831995-03-01 10:34:45 +00007281#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007282/*[clinic input]
7283os.getegid
7284
7285Return the current process's effective group id.
7286[clinic start generated code]*/
7287
Larry Hastings2f936352014-08-05 14:04:04 +10007288static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007289os_getegid_impl(PyObject *module)
7290/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007291{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007292 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007293}
Larry Hastings2f936352014-08-05 14:04:04 +10007294#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007296
Guido van Rossumad0ee831995-03-01 10:34:45 +00007297#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007298/*[clinic input]
7299os.geteuid
7300
7301Return the current process's effective user id.
7302[clinic start generated code]*/
7303
Larry Hastings2f936352014-08-05 14:04:04 +10007304static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007305os_geteuid_impl(PyObject *module)
7306/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007307{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007308 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007309}
Larry Hastings2f936352014-08-05 14:04:04 +10007310#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007311
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007312
Guido van Rossumad0ee831995-03-01 10:34:45 +00007313#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007314/*[clinic input]
7315os.getgid
7316
7317Return the current process's group id.
7318[clinic start generated code]*/
7319
Larry Hastings2f936352014-08-05 14:04:04 +10007320static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007321os_getgid_impl(PyObject *module)
7322/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007323{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007324 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007325}
Larry Hastings2f936352014-08-05 14:04:04 +10007326#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007328
Berker Peksag39404992016-09-15 20:45:16 +03007329#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10007330/*[clinic input]
7331os.getpid
7332
7333Return the current process id.
7334[clinic start generated code]*/
7335
Larry Hastings2f936352014-08-05 14:04:04 +10007336static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007337os_getpid_impl(PyObject *module)
7338/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007339{
Victor Stinner8c62be82010-05-06 00:08:46 +00007340 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00007341}
Berker Peksag39404992016-09-15 20:45:16 +03007342#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007343
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007344#ifdef NGROUPS_MAX
7345#define MAX_GROUPS NGROUPS_MAX
7346#else
7347 /* defined to be 16 on Solaris7, so this should be a small number */
7348#define MAX_GROUPS 64
7349#endif
7350
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007351#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10007352
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007353#ifdef __APPLE__
7354/*[clinic input]
7355os.getgrouplist
7356
7357 user: str
7358 username to lookup
7359 group as basegid: int
7360 base group id of the user
7361 /
7362
7363Returns a list of groups to which a user belongs.
7364[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007365
7366static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007367os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
7368/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
7369#else
7370/*[clinic input]
7371os.getgrouplist
7372
7373 user: str
7374 username to lookup
7375 group as basegid: gid_t
7376 base group id of the user
7377 /
7378
7379Returns a list of groups to which a user belongs.
7380[clinic start generated code]*/
7381
7382static PyObject *
7383os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
7384/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
7385#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007386{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007387 int i, ngroups;
7388 PyObject *list;
7389#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007390 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007391#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007392 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007393#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007394
7395 /*
7396 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7397 * number of supplimental groups a users can belong to.
7398 * We have to increment it by one because
7399 * getgrouplist() returns both the supplemental groups
7400 * and the primary group, i.e. all of the groups the
7401 * user belongs to.
7402 */
7403 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007404
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007405 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007406#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007407 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007408#else
7409 groups = PyMem_New(gid_t, ngroups);
7410#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007411 if (groups == NULL) {
7412 return PyErr_NoMemory();
7413 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007414
7415 int old_ngroups = ngroups;
7416 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7417 /* Success */
7418 break;
7419 }
7420
7421 /* getgrouplist() fails if the group list is too small */
7422 PyMem_Free(groups);
7423
7424 if (ngroups > old_ngroups) {
7425 /* If the group list is too small, the glibc implementation of
7426 getgrouplist() sets ngroups to the total number of groups and
7427 returns -1. */
7428 }
7429 else {
7430 /* Double the group list size */
7431 if (ngroups > INT_MAX / 2) {
7432 return PyErr_NoMemory();
7433 }
7434 ngroups *= 2;
7435 }
7436
7437 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007438 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007439
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007440#ifdef _Py_MEMORY_SANITIZER
7441 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7442 __msan_unpoison(&ngroups, sizeof(ngroups));
7443 __msan_unpoison(groups, ngroups*sizeof(*groups));
7444#endif
7445
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007446 list = PyList_New(ngroups);
7447 if (list == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01007448 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007449 return NULL;
7450 }
7451
7452 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007453#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007454 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007455#else
7456 PyObject *o = _PyLong_FromGid(groups[i]);
7457#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007458 if (o == NULL) {
7459 Py_DECREF(list);
Victor Stinner00d7abd2020-12-01 09:56:42 +01007460 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007461 return NULL;
7462 }
7463 PyList_SET_ITEM(list, i, o);
7464 }
7465
Victor Stinner00d7abd2020-12-01 09:56:42 +01007466 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007467
7468 return list;
7469}
Larry Hastings2f936352014-08-05 14:04:04 +10007470#endif /* HAVE_GETGROUPLIST */
7471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007472
Fred Drakec9680921999-12-13 16:37:25 +00007473#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007474/*[clinic input]
7475os.getgroups
7476
7477Return list of supplemental group IDs for the process.
7478[clinic start generated code]*/
7479
Larry Hastings2f936352014-08-05 14:04:04 +10007480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007481os_getgroups_impl(PyObject *module)
7482/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007483{
7484 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007485 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007486
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007487 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007488 * This is a helper variable to store the intermediate result when
7489 * that happens.
7490 *
7491 * To keep the code readable the OSX behaviour is unconditional,
7492 * according to the POSIX spec this should be safe on all unix-y
7493 * systems.
7494 */
7495 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007496 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007497
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007498#ifdef __APPLE__
7499 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7500 * there are more groups than can fit in grouplist. Therefore, on OS X
7501 * always first call getgroups with length 0 to get the actual number
7502 * of groups.
7503 */
7504 n = getgroups(0, NULL);
7505 if (n < 0) {
7506 return posix_error();
7507 } else if (n <= MAX_GROUPS) {
7508 /* groups will fit in existing array */
7509 alt_grouplist = grouplist;
7510 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007511 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007512 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007513 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007514 }
7515 }
7516
7517 n = getgroups(n, alt_grouplist);
7518 if (n == -1) {
7519 if (alt_grouplist != grouplist) {
7520 PyMem_Free(alt_grouplist);
7521 }
7522 return posix_error();
7523 }
7524#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007525 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007526 if (n < 0) {
7527 if (errno == EINVAL) {
7528 n = getgroups(0, NULL);
7529 if (n == -1) {
7530 return posix_error();
7531 }
7532 if (n == 0) {
7533 /* Avoid malloc(0) */
7534 alt_grouplist = grouplist;
7535 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007536 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007537 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007538 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007539 }
7540 n = getgroups(n, alt_grouplist);
7541 if (n == -1) {
7542 PyMem_Free(alt_grouplist);
7543 return posix_error();
7544 }
7545 }
7546 } else {
7547 return posix_error();
7548 }
7549 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007550#endif
7551
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007552 result = PyList_New(n);
7553 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007554 int i;
7555 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007556 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007557 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007558 Py_DECREF(result);
7559 result = NULL;
7560 break;
Fred Drakec9680921999-12-13 16:37:25 +00007561 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007563 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007564 }
7565
7566 if (alt_grouplist != grouplist) {
7567 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007568 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007569
Fred Drakec9680921999-12-13 16:37:25 +00007570 return result;
7571}
Larry Hastings2f936352014-08-05 14:04:04 +10007572#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007573
Antoine Pitroub7572f02009-12-02 20:46:48 +00007574#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007575#ifdef __APPLE__
7576/*[clinic input]
7577os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007578
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007579 username as oname: FSConverter
7580 gid: int
7581 /
7582
7583Initialize the group access list.
7584
7585Call the system initgroups() to initialize the group access list with all of
7586the groups of which the specified username is a member, plus the specified
7587group id.
7588[clinic start generated code]*/
7589
Antoine Pitroub7572f02009-12-02 20:46:48 +00007590static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007591os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7592/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7593#else
7594/*[clinic input]
7595os.initgroups
7596
7597 username as oname: FSConverter
7598 gid: gid_t
7599 /
7600
7601Initialize the group access list.
7602
7603Call the system initgroups() to initialize the group access list with all of
7604the groups of which the specified username is a member, plus the specified
7605group id.
7606[clinic start generated code]*/
7607
7608static PyObject *
7609os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7610/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7611#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007612{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007613 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007614
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007615 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007617
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007618 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007619}
Larry Hastings2f936352014-08-05 14:04:04 +10007620#endif /* HAVE_INITGROUPS */
7621
Antoine Pitroub7572f02009-12-02 20:46:48 +00007622
Martin v. Löwis606edc12002-06-13 21:09:11 +00007623#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007624/*[clinic input]
7625os.getpgid
7626
7627 pid: pid_t
7628
7629Call the system call getpgid(), and return the result.
7630[clinic start generated code]*/
7631
Larry Hastings2f936352014-08-05 14:04:04 +10007632static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007633os_getpgid_impl(PyObject *module, pid_t pid)
7634/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007635{
7636 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007637 if (pgid < 0)
7638 return posix_error();
7639 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007640}
7641#endif /* HAVE_GETPGID */
7642
7643
Guido van Rossumb6775db1994-08-01 11:34:53 +00007644#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007645/*[clinic input]
7646os.getpgrp
7647
7648Return the current process group id.
7649[clinic start generated code]*/
7650
Larry Hastings2f936352014-08-05 14:04:04 +10007651static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007652os_getpgrp_impl(PyObject *module)
7653/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007654{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007655#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007656 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007657#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007658 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007659#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007660}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007661#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007662
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007663
Guido van Rossumb6775db1994-08-01 11:34:53 +00007664#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007665/*[clinic input]
7666os.setpgrp
7667
7668Make the current process the leader of its process group.
7669[clinic start generated code]*/
7670
Larry Hastings2f936352014-08-05 14:04:04 +10007671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007672os_setpgrp_impl(PyObject *module)
7673/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007674{
Guido van Rossum64933891994-10-20 21:56:42 +00007675#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007676 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007677#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007678 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007679#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007680 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007681 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007682}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007683#endif /* HAVE_SETPGRP */
7684
Guido van Rossumad0ee831995-03-01 10:34:45 +00007685#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007686
7687#ifdef MS_WINDOWS
7688#include <tlhelp32.h>
7689
7690static PyObject*
7691win32_getppid()
7692{
7693 HANDLE snapshot;
7694 pid_t mypid;
7695 PyObject* result = NULL;
7696 BOOL have_record;
7697 PROCESSENTRY32 pe;
7698
7699 mypid = getpid(); /* This function never fails */
7700
7701 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7702 if (snapshot == INVALID_HANDLE_VALUE)
7703 return PyErr_SetFromWindowsErr(GetLastError());
7704
7705 pe.dwSize = sizeof(pe);
7706 have_record = Process32First(snapshot, &pe);
7707 while (have_record) {
7708 if (mypid == (pid_t)pe.th32ProcessID) {
7709 /* We could cache the ulong value in a static variable. */
7710 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7711 break;
7712 }
7713
7714 have_record = Process32Next(snapshot, &pe);
7715 }
7716
7717 /* If our loop exits and our pid was not found (result will be NULL)
7718 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7719 * error anyway, so let's raise it. */
7720 if (!result)
7721 result = PyErr_SetFromWindowsErr(GetLastError());
7722
7723 CloseHandle(snapshot);
7724
7725 return result;
7726}
7727#endif /*MS_WINDOWS*/
7728
Larry Hastings2f936352014-08-05 14:04:04 +10007729
7730/*[clinic input]
7731os.getppid
7732
7733Return the parent's process id.
7734
7735If the parent process has already exited, Windows machines will still
7736return its id; others systems will return the id of the 'init' process (1).
7737[clinic start generated code]*/
7738
Larry Hastings2f936352014-08-05 14:04:04 +10007739static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007740os_getppid_impl(PyObject *module)
7741/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007742{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007743#ifdef MS_WINDOWS
7744 return win32_getppid();
7745#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007746 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007747#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007748}
7749#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007750
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007751
Fred Drake12c6e2d1999-12-14 21:25:03 +00007752#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007753/*[clinic input]
7754os.getlogin
7755
7756Return the actual login name.
7757[clinic start generated code]*/
7758
Larry Hastings2f936352014-08-05 14:04:04 +10007759static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007760os_getlogin_impl(PyObject *module)
7761/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007762{
Victor Stinner8c62be82010-05-06 00:08:46 +00007763 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007764#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007765 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007766 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007767
7768 if (GetUserNameW(user_name, &num_chars)) {
7769 /* num_chars is the number of unicode chars plus null terminator */
7770 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007771 }
7772 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007773 result = PyErr_SetFromWindowsErr(GetLastError());
7774#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 char *name;
7776 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007777
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 errno = 0;
7779 name = getlogin();
7780 if (name == NULL) {
7781 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007782 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007783 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007784 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 }
7786 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007787 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007789#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007790 return result;
7791}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007792#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007793
Larry Hastings2f936352014-08-05 14:04:04 +10007794
Guido van Rossumad0ee831995-03-01 10:34:45 +00007795#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007796/*[clinic input]
7797os.getuid
7798
7799Return the current process's user id.
7800[clinic start generated code]*/
7801
Larry Hastings2f936352014-08-05 14:04:04 +10007802static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007803os_getuid_impl(PyObject *module)
7804/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007805{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007806 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007807}
Larry Hastings2f936352014-08-05 14:04:04 +10007808#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007809
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007810
Brian Curtineb24d742010-04-12 17:16:38 +00007811#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007812#define HAVE_KILL
7813#endif /* MS_WINDOWS */
7814
7815#ifdef HAVE_KILL
7816/*[clinic input]
7817os.kill
7818
7819 pid: pid_t
7820 signal: Py_ssize_t
7821 /
7822
7823Kill a process with a signal.
7824[clinic start generated code]*/
7825
Larry Hastings2f936352014-08-05 14:04:04 +10007826static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007827os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7828/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007829{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007830 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7831 return NULL;
7832 }
7833#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007834 if (kill(pid, (int)signal) == -1)
7835 return posix_error();
7836 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007837#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007838 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007839 DWORD sig = (DWORD)signal;
7840 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007841 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007842
Victor Stinner8c62be82010-05-06 00:08:46 +00007843 /* Console processes which share a common console can be sent CTRL+C or
7844 CTRL+BREAK events, provided they handle said events. */
7845 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007846 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 err = GetLastError();
7848 PyErr_SetFromWindowsErr(err);
7849 }
7850 else
7851 Py_RETURN_NONE;
7852 }
Brian Curtineb24d742010-04-12 17:16:38 +00007853
Victor Stinner8c62be82010-05-06 00:08:46 +00007854 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7855 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007856 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 if (handle == NULL) {
7858 err = GetLastError();
7859 return PyErr_SetFromWindowsErr(err);
7860 }
Brian Curtineb24d742010-04-12 17:16:38 +00007861
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 if (TerminateProcess(handle, sig) == 0) {
7863 err = GetLastError();
7864 result = PyErr_SetFromWindowsErr(err);
7865 } else {
7866 Py_INCREF(Py_None);
7867 result = Py_None;
7868 }
Brian Curtineb24d742010-04-12 17:16:38 +00007869
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 CloseHandle(handle);
7871 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007872#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007873}
Larry Hastings2f936352014-08-05 14:04:04 +10007874#endif /* HAVE_KILL */
7875
7876
7877#ifdef HAVE_KILLPG
7878/*[clinic input]
7879os.killpg
7880
7881 pgid: pid_t
7882 signal: int
7883 /
7884
7885Kill a process group with a signal.
7886[clinic start generated code]*/
7887
Larry Hastings2f936352014-08-05 14:04:04 +10007888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007889os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7890/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007891{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007892 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7893 return NULL;
7894 }
Larry Hastings2f936352014-08-05 14:04:04 +10007895 /* XXX some man pages make the `pgid` parameter an int, others
7896 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7897 take the same type. Moreover, pid_t is always at least as wide as
7898 int (else compilation of this module fails), which is safe. */
7899 if (killpg(pgid, signal) == -1)
7900 return posix_error();
7901 Py_RETURN_NONE;
7902}
7903#endif /* HAVE_KILLPG */
7904
Brian Curtineb24d742010-04-12 17:16:38 +00007905
Guido van Rossumc0125471996-06-28 18:55:32 +00007906#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007907#ifdef HAVE_SYS_LOCK_H
7908#include <sys/lock.h>
7909#endif
7910
Larry Hastings2f936352014-08-05 14:04:04 +10007911/*[clinic input]
7912os.plock
7913 op: int
7914 /
7915
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007916Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007917[clinic start generated code]*/
7918
Larry Hastings2f936352014-08-05 14:04:04 +10007919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007920os_plock_impl(PyObject *module, int op)
7921/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007922{
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 if (plock(op) == -1)
7924 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007925 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007926}
Larry Hastings2f936352014-08-05 14:04:04 +10007927#endif /* HAVE_PLOCK */
7928
Guido van Rossumc0125471996-06-28 18:55:32 +00007929
Guido van Rossumb6775db1994-08-01 11:34:53 +00007930#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007931/*[clinic input]
7932os.setuid
7933
7934 uid: uid_t
7935 /
7936
7937Set the current process's user id.
7938[clinic start generated code]*/
7939
Larry Hastings2f936352014-08-05 14:04:04 +10007940static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007941os_setuid_impl(PyObject *module, uid_t uid)
7942/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007943{
Victor Stinner8c62be82010-05-06 00:08:46 +00007944 if (setuid(uid) < 0)
7945 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007946 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007947}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007948#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007950
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007951#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007952/*[clinic input]
7953os.seteuid
7954
7955 euid: uid_t
7956 /
7957
7958Set the current process's effective user id.
7959[clinic start generated code]*/
7960
Larry Hastings2f936352014-08-05 14:04:04 +10007961static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007962os_seteuid_impl(PyObject *module, uid_t euid)
7963/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007964{
7965 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007967 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007968}
7969#endif /* HAVE_SETEUID */
7970
Larry Hastings2f936352014-08-05 14:04:04 +10007971
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007972#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007973/*[clinic input]
7974os.setegid
7975
7976 egid: gid_t
7977 /
7978
7979Set the current process's effective group id.
7980[clinic start generated code]*/
7981
Larry Hastings2f936352014-08-05 14:04:04 +10007982static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007983os_setegid_impl(PyObject *module, gid_t egid)
7984/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007985{
7986 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007987 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007988 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007989}
7990#endif /* HAVE_SETEGID */
7991
Larry Hastings2f936352014-08-05 14:04:04 +10007992
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007993#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10007994/*[clinic input]
7995os.setreuid
7996
7997 ruid: uid_t
7998 euid: uid_t
7999 /
8000
8001Set the current process's real and effective user ids.
8002[clinic start generated code]*/
8003
Larry Hastings2f936352014-08-05 14:04:04 +10008004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008005os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
8006/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008007{
Victor Stinner8c62be82010-05-06 00:08:46 +00008008 if (setreuid(ruid, euid) < 0) {
8009 return posix_error();
8010 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008011 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00008012 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008013}
8014#endif /* HAVE_SETREUID */
8015
Larry Hastings2f936352014-08-05 14:04:04 +10008016
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008017#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10008018/*[clinic input]
8019os.setregid
8020
8021 rgid: gid_t
8022 egid: gid_t
8023 /
8024
8025Set the current process's real and effective group ids.
8026[clinic start generated code]*/
8027
Larry Hastings2f936352014-08-05 14:04:04 +10008028static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008029os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
8030/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008031{
8032 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008033 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008034 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008035}
8036#endif /* HAVE_SETREGID */
8037
Larry Hastings2f936352014-08-05 14:04:04 +10008038
Guido van Rossumb6775db1994-08-01 11:34:53 +00008039#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10008040/*[clinic input]
8041os.setgid
8042 gid: gid_t
8043 /
8044
8045Set the current process's group id.
8046[clinic start generated code]*/
8047
Larry Hastings2f936352014-08-05 14:04:04 +10008048static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008049os_setgid_impl(PyObject *module, gid_t gid)
8050/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008051{
Victor Stinner8c62be82010-05-06 00:08:46 +00008052 if (setgid(gid) < 0)
8053 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008054 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008055}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008056#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008057
Larry Hastings2f936352014-08-05 14:04:04 +10008058
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008059#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10008060/*[clinic input]
8061os.setgroups
8062
8063 groups: object
8064 /
8065
8066Set the groups of the current process to list.
8067[clinic start generated code]*/
8068
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008069static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008070os_setgroups(PyObject *module, PyObject *groups)
8071/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008072{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008073 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00008074 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00008075
Victor Stinner8c62be82010-05-06 00:08:46 +00008076 if (!PySequence_Check(groups)) {
8077 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
8078 return NULL;
8079 }
8080 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008081 if (len < 0) {
8082 return NULL;
8083 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 if (len > MAX_GROUPS) {
8085 PyErr_SetString(PyExc_ValueError, "too many groups");
8086 return NULL;
8087 }
8088 for(i = 0; i < len; i++) {
8089 PyObject *elem;
8090 elem = PySequence_GetItem(groups, i);
8091 if (!elem)
8092 return NULL;
8093 if (!PyLong_Check(elem)) {
8094 PyErr_SetString(PyExc_TypeError,
8095 "groups must be integers");
8096 Py_DECREF(elem);
8097 return NULL;
8098 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008099 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008100 Py_DECREF(elem);
8101 return NULL;
8102 }
8103 }
8104 Py_DECREF(elem);
8105 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008106
Victor Stinner8c62be82010-05-06 00:08:46 +00008107 if (setgroups(len, grouplist) < 0)
8108 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008109 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008110}
8111#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008112
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008113#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
8114static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008115wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008116{
Victor Stinner8c62be82010-05-06 00:08:46 +00008117 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08008118 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008119
Victor Stinner8c62be82010-05-06 00:08:46 +00008120 if (pid == -1)
8121 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008122
Zackery Spytz682107c2019-09-09 09:48:32 -06008123 // If wait succeeded but no child was ready to report status, ru will not
8124 // have been populated.
8125 if (pid == 0) {
8126 memset(ru, 0, sizeof(*ru));
8127 }
8128
Eddie Elizondob3966632019-11-05 07:16:14 -08008129 PyObject *m = PyImport_ImportModuleNoBlock("resource");
8130 if (m == NULL)
8131 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02008132 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08008133 Py_DECREF(m);
8134 if (struct_rusage == NULL)
8135 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008136
Victor Stinner8c62be82010-05-06 00:08:46 +00008137 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
8138 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08008139 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 if (!result)
8141 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008142
8143#ifndef doubletime
8144#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
8145#endif
8146
Victor Stinner8c62be82010-05-06 00:08:46 +00008147 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008148 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00008149 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008150 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008151#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
8153 SET_INT(result, 2, ru->ru_maxrss);
8154 SET_INT(result, 3, ru->ru_ixrss);
8155 SET_INT(result, 4, ru->ru_idrss);
8156 SET_INT(result, 5, ru->ru_isrss);
8157 SET_INT(result, 6, ru->ru_minflt);
8158 SET_INT(result, 7, ru->ru_majflt);
8159 SET_INT(result, 8, ru->ru_nswap);
8160 SET_INT(result, 9, ru->ru_inblock);
8161 SET_INT(result, 10, ru->ru_oublock);
8162 SET_INT(result, 11, ru->ru_msgsnd);
8163 SET_INT(result, 12, ru->ru_msgrcv);
8164 SET_INT(result, 13, ru->ru_nsignals);
8165 SET_INT(result, 14, ru->ru_nvcsw);
8166 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008167#undef SET_INT
8168
Victor Stinner8c62be82010-05-06 00:08:46 +00008169 if (PyErr_Occurred()) {
8170 Py_DECREF(result);
8171 return NULL;
8172 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008173
Victor Stinner8c62be82010-05-06 00:08:46 +00008174 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008175}
8176#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
8177
Larry Hastings2f936352014-08-05 14:04:04 +10008178
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008179#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10008180/*[clinic input]
8181os.wait3
8182
8183 options: int
8184Wait for completion of a child process.
8185
8186Returns a tuple of information about the child process:
8187 (pid, status, rusage)
8188[clinic start generated code]*/
8189
Larry Hastings2f936352014-08-05 14:04:04 +10008190static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008191os_wait3_impl(PyObject *module, int options)
8192/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008193{
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008195 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008196 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008197 WAIT_TYPE status;
8198 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008199
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008200 do {
8201 Py_BEGIN_ALLOW_THREADS
8202 pid = wait3(&status, options, &ru);
8203 Py_END_ALLOW_THREADS
8204 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8205 if (pid < 0)
8206 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008207
Victor Stinner1c2fa782020-05-10 11:05:29 +02008208 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008209}
8210#endif /* HAVE_WAIT3 */
8211
Larry Hastings2f936352014-08-05 14:04:04 +10008212
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008213#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10008214/*[clinic input]
8215
8216os.wait4
8217
8218 pid: pid_t
8219 options: int
8220
8221Wait for completion of a specific child process.
8222
8223Returns a tuple of information about the child process:
8224 (pid, status, rusage)
8225[clinic start generated code]*/
8226
Larry Hastings2f936352014-08-05 14:04:04 +10008227static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008228os_wait4_impl(PyObject *module, pid_t pid, int options)
8229/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008230{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008231 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008232 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008233 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008234 WAIT_TYPE status;
8235 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008236
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008237 do {
8238 Py_BEGIN_ALLOW_THREADS
8239 res = wait4(pid, &status, options, &ru);
8240 Py_END_ALLOW_THREADS
8241 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8242 if (res < 0)
8243 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008244
Victor Stinner1c2fa782020-05-10 11:05:29 +02008245 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008246}
8247#endif /* HAVE_WAIT4 */
8248
Larry Hastings2f936352014-08-05 14:04:04 +10008249
Ross Lagerwall7807c352011-03-17 20:20:30 +02008250#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10008251/*[clinic input]
8252os.waitid
8253
8254 idtype: idtype_t
8255 Must be one of be P_PID, P_PGID or P_ALL.
8256 id: id_t
8257 The id to wait on.
8258 options: int
8259 Constructed from the ORing of one or more of WEXITED, WSTOPPED
8260 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
8261 /
8262
8263Returns the result of waiting for a process or processes.
8264
8265Returns either waitid_result or None if WNOHANG is specified and there are
8266no children in a waitable state.
8267[clinic start generated code]*/
8268
Larry Hastings2f936352014-08-05 14:04:04 +10008269static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008270os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
8271/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008272{
8273 PyObject *result;
8274 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008275 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008276 siginfo_t si;
8277 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008278
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008279 do {
8280 Py_BEGIN_ALLOW_THREADS
8281 res = waitid(idtype, id, &si, options);
8282 Py_END_ALLOW_THREADS
8283 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8284 if (res < 0)
8285 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008286
8287 if (si.si_pid == 0)
8288 Py_RETURN_NONE;
8289
Hai Shif707d942020-03-16 21:15:01 +08008290 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008291 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008292 if (!result)
8293 return NULL;
8294
8295 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008296 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008297 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
8298 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
8299 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
8300 if (PyErr_Occurred()) {
8301 Py_DECREF(result);
8302 return NULL;
8303 }
8304
8305 return result;
8306}
Larry Hastings2f936352014-08-05 14:04:04 +10008307#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008308
Larry Hastings2f936352014-08-05 14:04:04 +10008309
8310#if defined(HAVE_WAITPID)
8311/*[clinic input]
8312os.waitpid
8313 pid: pid_t
8314 options: int
8315 /
8316
8317Wait for completion of a given child process.
8318
8319Returns a tuple of information regarding the child process:
8320 (pid, status)
8321
8322The options argument is ignored on Windows.
8323[clinic start generated code]*/
8324
Larry Hastings2f936352014-08-05 14:04:04 +10008325static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008326os_waitpid_impl(PyObject *module, pid_t pid, int options)
8327/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008328{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008329 pid_t res;
8330 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008331 WAIT_TYPE status;
8332 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008333
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008334 do {
8335 Py_BEGIN_ALLOW_THREADS
8336 res = waitpid(pid, &status, options);
8337 Py_END_ALLOW_THREADS
8338 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8339 if (res < 0)
8340 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008341
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008342 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00008343}
Tim Petersab034fa2002-02-01 11:27:43 +00008344#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00008345/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10008346/*[clinic input]
8347os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07008348 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10008349 options: int
8350 /
8351
8352Wait for completion of a given process.
8353
8354Returns a tuple of information regarding the process:
8355 (pid, status << 8)
8356
8357The options argument is ignored on Windows.
8358[clinic start generated code]*/
8359
Larry Hastings2f936352014-08-05 14:04:04 +10008360static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07008361os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07008362/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008363{
8364 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07008365 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008366 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008367
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008368 do {
8369 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08008370 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008371 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08008372 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008373 Py_END_ALLOW_THREADS
8374 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008375 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008376 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008377
Victor Stinner9bee32b2020-04-22 16:30:35 +02008378 unsigned long long ustatus = (unsigned int)status;
8379
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02008381 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00008382}
Larry Hastings2f936352014-08-05 14:04:04 +10008383#endif
8384
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008385
Guido van Rossumad0ee831995-03-01 10:34:45 +00008386#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10008387/*[clinic input]
8388os.wait
8389
8390Wait for completion of a child process.
8391
8392Returns a tuple of information about the child process:
8393 (pid, status)
8394[clinic start generated code]*/
8395
Larry Hastings2f936352014-08-05 14:04:04 +10008396static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008397os_wait_impl(PyObject *module)
8398/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008399{
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008401 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 WAIT_TYPE status;
8403 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008404
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008405 do {
8406 Py_BEGIN_ALLOW_THREADS
8407 pid = wait(&status);
8408 Py_END_ALLOW_THREADS
8409 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8410 if (pid < 0)
8411 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008412
Victor Stinner8c62be82010-05-06 00:08:46 +00008413 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008414}
Larry Hastings2f936352014-08-05 14:04:04 +10008415#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008416
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008417#if defined(__linux__) && defined(__NR_pidfd_open)
8418/*[clinic input]
8419os.pidfd_open
8420 pid: pid_t
8421 flags: unsigned_int = 0
8422
8423Return a file descriptor referring to the process *pid*.
8424
8425The descriptor can be used to perform process management without races and
8426signals.
8427[clinic start generated code]*/
8428
8429static PyObject *
8430os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8431/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8432{
8433 int fd = syscall(__NR_pidfd_open, pid, flags);
8434 if (fd < 0) {
8435 return posix_error();
8436 }
8437 return PyLong_FromLong(fd);
8438}
8439#endif
8440
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008441
Larry Hastings9cf065c2012-06-22 16:30:09 -07008442#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008443/*[clinic input]
8444os.readlink
8445
8446 path: path_t
8447 *
8448 dir_fd: dir_fd(requires='readlinkat') = None
8449
8450Return a string representing the path to which the symbolic link points.
8451
8452If dir_fd is not None, it should be a file descriptor open to a directory,
8453and path should be relative; path will then be relative to that directory.
8454
8455dir_fd may not be implemented on your platform. If it is unavailable,
8456using it will raise a NotImplementedError.
8457[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008458
Barry Warsaw53699e91996-12-10 23:23:01 +00008459static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008460os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8461/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008462{
Berker Peksage0b5b202018-08-15 13:03:41 +03008463#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008464 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008465 ssize_t length;
Ronald Oussoren41761932020-11-08 10:05:27 +01008466#ifdef HAVE_READLINKAT
8467 int readlinkat_unavailable = 0;
8468#endif
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008469
8470 Py_BEGIN_ALLOW_THREADS
8471#ifdef HAVE_READLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01008472 if (dir_fd != DEFAULT_DIR_FD) {
8473 if (HAVE_READLINKAT_RUNTIME) {
8474 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8475 } else {
8476 readlinkat_unavailable = 1;
8477 }
8478 } else
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008479#endif
8480 length = readlink(path->narrow, buffer, MAXPATHLEN);
8481 Py_END_ALLOW_THREADS
8482
Ronald Oussoren41761932020-11-08 10:05:27 +01008483#ifdef HAVE_READLINKAT
8484 if (readlinkat_unavailable) {
8485 argument_unavailable_error(NULL, "dir_fd");
8486 return NULL;
8487 }
8488#endif
8489
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008490 if (length < 0) {
8491 return path_error(path);
8492 }
8493 buffer[length] = '\0';
8494
8495 if (PyUnicode_Check(path->object))
8496 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8497 else
8498 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008499#elif defined(MS_WINDOWS)
8500 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008501 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008502 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008503 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8504 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008505 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008506
Larry Hastings2f936352014-08-05 14:04:04 +10008507 /* First get a handle to the reparse point */
8508 Py_BEGIN_ALLOW_THREADS
8509 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008510 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008511 0,
8512 0,
8513 0,
8514 OPEN_EXISTING,
8515 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8516 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008517 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8518 /* New call DeviceIoControl to read the reparse point */
8519 io_result = DeviceIoControl(
8520 reparse_point_handle,
8521 FSCTL_GET_REPARSE_POINT,
8522 0, 0, /* in buffer */
8523 target_buffer, sizeof(target_buffer),
8524 &n_bytes_returned,
8525 0 /* we're not using OVERLAPPED_IO */
8526 );
8527 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008528 }
Larry Hastings2f936352014-08-05 14:04:04 +10008529 Py_END_ALLOW_THREADS
8530
Berker Peksage0b5b202018-08-15 13:03:41 +03008531 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008532 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008533 }
Larry Hastings2f936352014-08-05 14:04:04 +10008534
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008535 wchar_t *name = NULL;
8536 Py_ssize_t nameLen = 0;
8537 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008538 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008539 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8540 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8541 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008542 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008543 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8544 {
8545 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8546 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8547 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8548 }
8549 else
8550 {
8551 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8552 }
8553 if (name) {
8554 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8555 /* Our buffer is mutable, so this is okay */
8556 name[1] = L'\\';
8557 }
8558 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008559 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008560 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8561 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008562 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008563 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008564#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008565}
Berker Peksage0b5b202018-08-15 13:03:41 +03008566#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008567
Larry Hastings9cf065c2012-06-22 16:30:09 -07008568#if defined(MS_WINDOWS)
8569
Steve Dower6921e732018-03-05 14:26:08 -08008570/* Remove the last portion of the path - return 0 on success */
8571static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008572_dirnameW(WCHAR *path)
8573{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008574 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008575 size_t length = wcsnlen_s(path, MAX_PATH);
8576 if (length == MAX_PATH) {
8577 return -1;
8578 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008579
8580 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008581 for(ptr = path + length; ptr != path; ptr--) {
8582 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008583 break;
Steve Dower6921e732018-03-05 14:26:08 -08008584 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008585 }
8586 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008587 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008588}
8589
Minmin Gong7f21c9a2020-05-18 09:17:19 -07008590#endif
8591
8592#ifdef HAVE_SYMLINK
8593
8594#if defined(MS_WINDOWS)
8595
Victor Stinner31b3b922013-06-05 01:49:17 +02008596/* Is this path absolute? */
8597static int
8598_is_absW(const WCHAR *path)
8599{
Steve Dower6921e732018-03-05 14:26:08 -08008600 return path[0] == L'\\' || path[0] == L'/' ||
8601 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008602}
8603
Steve Dower6921e732018-03-05 14:26:08 -08008604/* join root and rest with a backslash - return 0 on success */
8605static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008606_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8607{
Victor Stinner31b3b922013-06-05 01:49:17 +02008608 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008609 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008610 }
8611
Steve Dower6921e732018-03-05 14:26:08 -08008612 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8613 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008614 }
Steve Dower6921e732018-03-05 14:26:08 -08008615
8616 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8617 return -1;
8618 }
8619
8620 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008621}
8622
Victor Stinner31b3b922013-06-05 01:49:17 +02008623/* Return True if the path at src relative to dest is a directory */
8624static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008625_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008626{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008627 WIN32_FILE_ATTRIBUTE_DATA src_info;
8628 WCHAR dest_parent[MAX_PATH];
8629 WCHAR src_resolved[MAX_PATH] = L"";
8630
8631 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008632 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8633 _dirnameW(dest_parent)) {
8634 return 0;
8635 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008636 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008637 if (_joinW(src_resolved, dest_parent, src)) {
8638 return 0;
8639 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008640 return (
8641 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8642 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8643 );
8644}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008645#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008646
Larry Hastings2f936352014-08-05 14:04:04 +10008647
8648/*[clinic input]
8649os.symlink
8650 src: path_t
8651 dst: path_t
8652 target_is_directory: bool = False
8653 *
8654 dir_fd: dir_fd(requires='symlinkat')=None
8655
8656# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8657
8658Create a symbolic link pointing to src named dst.
8659
8660target_is_directory is required on Windows if the target is to be
8661 interpreted as a directory. (On Windows, symlink requires
8662 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8663 target_is_directory is ignored on non-Windows platforms.
8664
8665If dir_fd is not None, it should be a file descriptor open to a directory,
8666 and path should be relative; path will then be relative to that directory.
8667dir_fd may not be implemented on your platform.
8668 If it is unavailable, using it will raise a NotImplementedError.
8669
8670[clinic start generated code]*/
8671
Larry Hastings2f936352014-08-05 14:04:04 +10008672static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008673os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008674 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008675/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008676{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008677#ifdef MS_WINDOWS
8678 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008679 DWORD flags = 0;
8680
8681 /* Assumed true, set to false if detected to not be available. */
8682 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008683#else
8684 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01008685#ifdef HAVE_SYMLINKAT
8686 int symlinkat_unavailable = 0;
8687#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07008688#endif
8689
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008690 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8691 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8692 return NULL;
8693 }
8694
Larry Hastings9cf065c2012-06-22 16:30:09 -07008695#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008696
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008697 if (windows_has_symlink_unprivileged_flag) {
8698 /* Allow non-admin symlinks if system allows it. */
8699 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8700 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008701
Larry Hastings9cf065c2012-06-22 16:30:09 -07008702 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008703 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008704 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8705 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8706 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8707 }
8708
8709 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008710 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008711 Py_END_ALLOW_THREADS
8712
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008713 if (windows_has_symlink_unprivileged_flag && !result &&
8714 ERROR_INVALID_PARAMETER == GetLastError()) {
8715
8716 Py_BEGIN_ALLOW_THREADS
8717 _Py_BEGIN_SUPPRESS_IPH
8718 /* This error might be caused by
8719 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8720 Try again, and update windows_has_symlink_unprivileged_flag if we
8721 are successful this time.
8722
8723 NOTE: There is a risk of a race condition here if there are other
8724 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8725 another process (or thread) changes that condition in between our
8726 calls to CreateSymbolicLink.
8727 */
8728 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8729 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8730 _Py_END_SUPPRESS_IPH
8731 Py_END_ALLOW_THREADS
8732
8733 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8734 windows_has_symlink_unprivileged_flag = FALSE;
8735 }
8736 }
8737
Larry Hastings2f936352014-08-05 14:04:04 +10008738 if (!result)
8739 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008740
8741#else
8742
Steve Dower6921e732018-03-05 14:26:08 -08008743 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8744 PyErr_SetString(PyExc_ValueError,
8745 "symlink: src and dst must be the same type");
8746 return NULL;
8747 }
8748
Larry Hastings9cf065c2012-06-22 16:30:09 -07008749 Py_BEGIN_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01008750#ifdef HAVE_SYMLINKAT
8751 if (dir_fd != DEFAULT_DIR_FD) {
8752 if (HAVE_SYMLINKAT_RUNTIME) {
8753 result = symlinkat(src->narrow, dir_fd, dst->narrow);
8754 } else {
8755 symlinkat_unavailable = 1;
8756 }
8757 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008758#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008759 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008760 Py_END_ALLOW_THREADS
8761
Ronald Oussoren41761932020-11-08 10:05:27 +01008762#ifdef HAVE_SYMLINKAT
8763 if (symlinkat_unavailable) {
8764 argument_unavailable_error(NULL, "dir_fd");
8765 return NULL;
8766 }
8767#endif
8768
Larry Hastings2f936352014-08-05 14:04:04 +10008769 if (result)
8770 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008771#endif
8772
Larry Hastings2f936352014-08-05 14:04:04 +10008773 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008774}
8775#endif /* HAVE_SYMLINK */
8776
Larry Hastings9cf065c2012-06-22 16:30:09 -07008777
Brian Curtind40e6f72010-07-08 21:39:08 +00008778
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008779
Larry Hastings605a62d2012-06-24 04:33:36 -07008780static PyStructSequence_Field times_result_fields[] = {
8781 {"user", "user time"},
8782 {"system", "system time"},
8783 {"children_user", "user time of children"},
8784 {"children_system", "system time of children"},
8785 {"elapsed", "elapsed time since an arbitrary point in the past"},
8786 {NULL}
8787};
8788
8789PyDoc_STRVAR(times_result__doc__,
8790"times_result: Result from os.times().\n\n\
8791This object may be accessed either as a tuple of\n\
8792 (user, system, children_user, children_system, elapsed),\n\
8793or via the attributes user, system, children_user, children_system,\n\
8794and elapsed.\n\
8795\n\
8796See os.times for more information.");
8797
8798static PyStructSequence_Desc times_result_desc = {
8799 "times_result", /* name */
8800 times_result__doc__, /* doc */
8801 times_result_fields,
8802 5
8803};
8804
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008805#ifdef MS_WINDOWS
8806#define HAVE_TIMES /* mandatory, for the method table */
8807#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008808
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008809#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008810
8811static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008812build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008813 double children_user, double children_system,
8814 double elapsed)
8815{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008816 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008817 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008818 if (value == NULL)
8819 return NULL;
8820
8821#define SET(i, field) \
8822 { \
8823 PyObject *o = PyFloat_FromDouble(field); \
8824 if (!o) { \
8825 Py_DECREF(value); \
8826 return NULL; \
8827 } \
8828 PyStructSequence_SET_ITEM(value, i, o); \
8829 } \
8830
8831 SET(0, user);
8832 SET(1, system);
8833 SET(2, children_user);
8834 SET(3, children_system);
8835 SET(4, elapsed);
8836
8837#undef SET
8838
8839 return value;
8840}
8841
Larry Hastings605a62d2012-06-24 04:33:36 -07008842
Larry Hastings2f936352014-08-05 14:04:04 +10008843#ifndef MS_WINDOWS
8844#define NEED_TICKS_PER_SECOND
8845static long ticks_per_second = -1;
8846#endif /* MS_WINDOWS */
8847
8848/*[clinic input]
8849os.times
8850
8851Return a collection containing process timing information.
8852
8853The object returned behaves like a named tuple with these fields:
8854 (utime, stime, cutime, cstime, elapsed_time)
8855All fields are floating point numbers.
8856[clinic start generated code]*/
8857
Larry Hastings2f936352014-08-05 14:04:04 +10008858static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008859os_times_impl(PyObject *module)
8860/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008861#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008862{
Victor Stinner8c62be82010-05-06 00:08:46 +00008863 FILETIME create, exit, kernel, user;
8864 HANDLE hProc;
8865 hProc = GetCurrentProcess();
8866 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8867 /* The fields of a FILETIME structure are the hi and lo part
8868 of a 64-bit value expressed in 100 nanosecond units.
8869 1e7 is one second in such units; 1e-7 the inverse.
8870 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8871 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008872 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 (double)(user.dwHighDateTime*429.4967296 +
8874 user.dwLowDateTime*1e-7),
8875 (double)(kernel.dwHighDateTime*429.4967296 +
8876 kernel.dwLowDateTime*1e-7),
8877 (double)0,
8878 (double)0,
8879 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008880}
Larry Hastings2f936352014-08-05 14:04:04 +10008881#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008882{
Larry Hastings2f936352014-08-05 14:04:04 +10008883
8884
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008885 struct tms t;
8886 clock_t c;
8887 errno = 0;
8888 c = times(&t);
8889 if (c == (clock_t) -1)
8890 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008891 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008892 (double)t.tms_utime / ticks_per_second,
8893 (double)t.tms_stime / ticks_per_second,
8894 (double)t.tms_cutime / ticks_per_second,
8895 (double)t.tms_cstime / ticks_per_second,
8896 (double)c / ticks_per_second);
8897}
Larry Hastings2f936352014-08-05 14:04:04 +10008898#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008899#endif /* HAVE_TIMES */
8900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008901
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008902#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008903/*[clinic input]
8904os.getsid
8905
8906 pid: pid_t
8907 /
8908
8909Call the system call getsid(pid) and return the result.
8910[clinic start generated code]*/
8911
Larry Hastings2f936352014-08-05 14:04:04 +10008912static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008913os_getsid_impl(PyObject *module, pid_t pid)
8914/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008915{
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008917 sid = getsid(pid);
8918 if (sid < 0)
8919 return posix_error();
8920 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008921}
8922#endif /* HAVE_GETSID */
8923
8924
Guido van Rossumb6775db1994-08-01 11:34:53 +00008925#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008926/*[clinic input]
8927os.setsid
8928
8929Call the system call setsid().
8930[clinic start generated code]*/
8931
Larry Hastings2f936352014-08-05 14:04:04 +10008932static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008933os_setsid_impl(PyObject *module)
8934/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008935{
Victor Stinner8c62be82010-05-06 00:08:46 +00008936 if (setsid() < 0)
8937 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008938 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008939}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008940#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008941
Larry Hastings2f936352014-08-05 14:04:04 +10008942
Guido van Rossumb6775db1994-08-01 11:34:53 +00008943#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008944/*[clinic input]
8945os.setpgid
8946
8947 pid: pid_t
8948 pgrp: pid_t
8949 /
8950
8951Call the system call setpgid(pid, pgrp).
8952[clinic start generated code]*/
8953
Larry Hastings2f936352014-08-05 14:04:04 +10008954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008955os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8956/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008957{
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 if (setpgid(pid, pgrp) < 0)
8959 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008960 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008961}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008962#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008963
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008964
Guido van Rossumb6775db1994-08-01 11:34:53 +00008965#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008966/*[clinic input]
8967os.tcgetpgrp
8968
8969 fd: int
8970 /
8971
8972Return the process group associated with the terminal specified by fd.
8973[clinic start generated code]*/
8974
Larry Hastings2f936352014-08-05 14:04:04 +10008975static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008976os_tcgetpgrp_impl(PyObject *module, int fd)
8977/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008978{
8979 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008980 if (pgid < 0)
8981 return posix_error();
8982 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008983}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008984#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008986
Guido van Rossumb6775db1994-08-01 11:34:53 +00008987#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008988/*[clinic input]
8989os.tcsetpgrp
8990
8991 fd: int
8992 pgid: pid_t
8993 /
8994
8995Set the process group associated with the terminal specified by fd.
8996[clinic start generated code]*/
8997
Larry Hastings2f936352014-08-05 14:04:04 +10008998static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008999os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
9000/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009001{
Victor Stinner8c62be82010-05-06 00:08:46 +00009002 if (tcsetpgrp(fd, pgid) < 0)
9003 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009004 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00009005}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009006#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00009007
Guido van Rossum687dd131993-05-17 08:34:16 +00009008/* Functions acting on file descriptors */
9009
Victor Stinnerdaf45552013-08-28 00:53:59 +02009010#ifdef O_CLOEXEC
9011extern int _Py_open_cloexec_works;
9012#endif
9013
Larry Hastings2f936352014-08-05 14:04:04 +10009014
9015/*[clinic input]
9016os.open -> int
9017 path: path_t
9018 flags: int
9019 mode: int = 0o777
9020 *
9021 dir_fd: dir_fd(requires='openat') = None
9022
9023# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
9024
9025Open a file for low level IO. Returns a file descriptor (integer).
9026
9027If dir_fd is not None, it should be a file descriptor open to a directory,
9028 and path should be relative; path will then be relative to that directory.
9029dir_fd may not be implemented on your platform.
9030 If it is unavailable, using it will raise a NotImplementedError.
9031[clinic start generated code]*/
9032
Larry Hastings2f936352014-08-05 14:04:04 +10009033static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009034os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
9035/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009036{
9037 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009038 int async_err = 0;
Ronald Oussoren41761932020-11-08 10:05:27 +01009039#ifdef HAVE_OPENAT
9040 int openat_unavailable = 0;
9041#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009042
Victor Stinnerdaf45552013-08-28 00:53:59 +02009043#ifdef O_CLOEXEC
9044 int *atomic_flag_works = &_Py_open_cloexec_works;
9045#elif !defined(MS_WINDOWS)
9046 int *atomic_flag_works = NULL;
9047#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00009048
Victor Stinnerdaf45552013-08-28 00:53:59 +02009049#ifdef MS_WINDOWS
9050 flags |= O_NOINHERIT;
9051#elif defined(O_CLOEXEC)
9052 flags |= O_CLOEXEC;
9053#endif
9054
Steve Dowerb82e17e2019-05-23 08:45:22 -07009055 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
9056 return -1;
9057 }
9058
Steve Dower8fc89802015-04-12 00:26:27 -04009059 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009060 do {
9061 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07009062#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009063 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009064#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07009065#ifdef HAVE_OPENAT
Ronald Oussoren41761932020-11-08 10:05:27 +01009066 if (dir_fd != DEFAULT_DIR_FD) {
9067 if (HAVE_OPENAT_RUNTIME) {
9068 fd = openat(dir_fd, path->narrow, flags, mode);
9069
9070 } else {
9071 openat_unavailable = 1;
9072 fd = -1;
9073 }
9074 } else
Steve Dower6230aaf2016-09-09 09:03:15 -07009075#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009076 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009077#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009078 Py_END_ALLOW_THREADS
9079 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009080 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00009081
Ronald Oussoren41761932020-11-08 10:05:27 +01009082#ifdef HAVE_OPENAT
9083 if (openat_unavailable) {
9084 argument_unavailable_error(NULL, "dir_fd");
9085 return -1;
9086 }
9087#endif
9088
Victor Stinnerd3ffd322015-09-15 10:11:03 +02009089 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009090 if (!async_err)
9091 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10009092 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009093 }
9094
Victor Stinnerdaf45552013-08-28 00:53:59 +02009095#ifndef MS_WINDOWS
9096 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
9097 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10009098 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009099 }
9100#endif
9101
Larry Hastings2f936352014-08-05 14:04:04 +10009102 return fd;
9103}
9104
9105
9106/*[clinic input]
9107os.close
9108
9109 fd: int
9110
9111Close a file descriptor.
9112[clinic start generated code]*/
9113
Barry Warsaw53699e91996-12-10 23:23:01 +00009114static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009115os_close_impl(PyObject *module, int fd)
9116/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009117{
Larry Hastings2f936352014-08-05 14:04:04 +10009118 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009119 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
9120 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
9121 * for more details.
9122 */
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009124 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009125 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04009126 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009127 Py_END_ALLOW_THREADS
9128 if (res < 0)
9129 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009130 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00009131}
9132
Larry Hastings2f936352014-08-05 14:04:04 +10009133/*[clinic input]
9134os.closerange
9135
9136 fd_low: int
9137 fd_high: int
9138 /
9139
9140Closes all file descriptors in [fd_low, fd_high), ignoring errors.
9141[clinic start generated code]*/
9142
Larry Hastings2f936352014-08-05 14:04:04 +10009143static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009144os_closerange_impl(PyObject *module, int fd_low, int fd_high)
9145/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009146{
Victor Stinner8c62be82010-05-06 00:08:46 +00009147 Py_BEGIN_ALLOW_THREADS
Kyle Evansc230fde2020-10-11 13:54:11 -05009148 _Py_closerange(fd_low, fd_high - 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00009149 Py_END_ALLOW_THREADS
9150 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00009151}
9152
9153
Larry Hastings2f936352014-08-05 14:04:04 +10009154/*[clinic input]
9155os.dup -> int
9156
9157 fd: int
9158 /
9159
9160Return a duplicate of a file descriptor.
9161[clinic start generated code]*/
9162
Larry Hastings2f936352014-08-05 14:04:04 +10009163static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009164os_dup_impl(PyObject *module, int fd)
9165/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009166{
9167 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00009168}
9169
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009170
Larry Hastings2f936352014-08-05 14:04:04 +10009171/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009172os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10009173 fd: int
9174 fd2: int
9175 inheritable: bool=True
9176
9177Duplicate file descriptor.
9178[clinic start generated code]*/
9179
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009180static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009181os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009182/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009183{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01009184 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009185#if defined(HAVE_DUP3) && \
9186 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
9187 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03009188 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009189#endif
9190
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009191 if (fd < 0 || fd2 < 0) {
9192 posix_error();
9193 return -1;
9194 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009195
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009196 /* dup2() can fail with EINTR if the target FD is already open, because it
9197 * then has to be closed. See os_close_impl() for why we don't handle EINTR
9198 * upon close(), and therefore below.
9199 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02009200#ifdef MS_WINDOWS
9201 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009202 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009203 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04009204 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009205 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009206 if (res < 0) {
9207 posix_error();
9208 return -1;
9209 }
9210 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02009211
9212 /* Character files like console cannot be make non-inheritable */
9213 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9214 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009215 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009216 }
9217
9218#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
9219 Py_BEGIN_ALLOW_THREADS
9220 if (!inheritable)
9221 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
9222 else
9223 res = dup2(fd, fd2);
9224 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009225 if (res < 0) {
9226 posix_error();
9227 return -1;
9228 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009229
9230#else
9231
9232#ifdef HAVE_DUP3
9233 if (!inheritable && dup3_works != 0) {
9234 Py_BEGIN_ALLOW_THREADS
9235 res = dup3(fd, fd2, O_CLOEXEC);
9236 Py_END_ALLOW_THREADS
9237 if (res < 0) {
9238 if (dup3_works == -1)
9239 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009240 if (dup3_works) {
9241 posix_error();
9242 return -1;
9243 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009244 }
9245 }
9246
9247 if (inheritable || dup3_works == 0)
9248 {
9249#endif
9250 Py_BEGIN_ALLOW_THREADS
9251 res = dup2(fd, fd2);
9252 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009253 if (res < 0) {
9254 posix_error();
9255 return -1;
9256 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009257
9258 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9259 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009260 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009261 }
9262#ifdef HAVE_DUP3
9263 }
9264#endif
9265
9266#endif
9267
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009268 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00009269}
9270
Larry Hastings2f936352014-08-05 14:04:04 +10009271
Ross Lagerwall7807c352011-03-17 20:20:30 +02009272#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10009273/*[clinic input]
9274os.lockf
9275
9276 fd: int
9277 An open file descriptor.
9278 command: int
9279 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
9280 length: Py_off_t
9281 The number of bytes to lock, starting at the current position.
9282 /
9283
9284Apply, test or remove a POSIX lock on an open file descriptor.
9285
9286[clinic start generated code]*/
9287
Larry Hastings2f936352014-08-05 14:04:04 +10009288static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009289os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
9290/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009291{
9292 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009293
Saiyang Gou7514f4f2020-02-12 23:47:42 -08009294 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
9295 return NULL;
9296 }
9297
Ross Lagerwall7807c352011-03-17 20:20:30 +02009298 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009299 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009300 Py_END_ALLOW_THREADS
9301
9302 if (res < 0)
9303 return posix_error();
9304
9305 Py_RETURN_NONE;
9306}
Larry Hastings2f936352014-08-05 14:04:04 +10009307#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009308
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009309
Larry Hastings2f936352014-08-05 14:04:04 +10009310/*[clinic input]
9311os.lseek -> Py_off_t
9312
9313 fd: int
9314 position: Py_off_t
9315 how: int
9316 /
9317
9318Set the position of a file descriptor. Return the new position.
9319
9320Return the new cursor position in number of bytes
9321relative to the beginning of the file.
9322[clinic start generated code]*/
9323
Larry Hastings2f936352014-08-05 14:04:04 +10009324static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009325os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
9326/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009327{
9328 Py_off_t result;
9329
Guido van Rossum687dd131993-05-17 08:34:16 +00009330#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
9332 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10009333 case 0: how = SEEK_SET; break;
9334 case 1: how = SEEK_CUR; break;
9335 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00009336 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009337#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009338
Victor Stinner8c62be82010-05-06 00:08:46 +00009339 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009340 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02009341#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009342 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009343#else
Larry Hastings2f936352014-08-05 14:04:04 +10009344 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009345#endif
Steve Dower8fc89802015-04-12 00:26:27 -04009346 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009348 if (result < 0)
9349 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00009350
Larry Hastings2f936352014-08-05 14:04:04 +10009351 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00009352}
9353
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009354
Larry Hastings2f936352014-08-05 14:04:04 +10009355/*[clinic input]
9356os.read
9357 fd: int
9358 length: Py_ssize_t
9359 /
9360
9361Read from a file descriptor. Returns a bytes object.
9362[clinic start generated code]*/
9363
Larry Hastings2f936352014-08-05 14:04:04 +10009364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009365os_read_impl(PyObject *module, int fd, Py_ssize_t length)
9366/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009367{
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 Py_ssize_t n;
9369 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10009370
9371 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 errno = EINVAL;
9373 return posix_error();
9374 }
Larry Hastings2f936352014-08-05 14:04:04 +10009375
Victor Stinner9a0d7a72018-11-22 15:03:40 +01009376 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10009377
9378 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 if (buffer == NULL)
9380 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009381
Victor Stinner66aab0c2015-03-19 22:53:20 +01009382 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
9383 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01009385 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 }
Larry Hastings2f936352014-08-05 14:04:04 +10009387
9388 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10009390
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00009392}
9393
Ross Lagerwall7807c352011-03-17 20:20:30 +02009394#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009395 || defined(__APPLE__))) \
9396 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9397 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9398static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009399iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009400{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009401 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009402
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009403 *iov = PyMem_New(struct iovec, cnt);
9404 if (*iov == NULL) {
9405 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009406 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009407 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009408
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009409 *buf = PyMem_New(Py_buffer, cnt);
9410 if (*buf == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01009411 PyMem_Free(*iov);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009412 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009413 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009414 }
9415
9416 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009417 PyObject *item = PySequence_GetItem(seq, i);
9418 if (item == NULL)
9419 goto fail;
9420 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9421 Py_DECREF(item);
9422 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009423 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009424 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009425 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009426 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009427 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009428 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009429
9430fail:
Victor Stinner00d7abd2020-12-01 09:56:42 +01009431 PyMem_Free(*iov);
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009432 for (j = 0; j < i; j++) {
9433 PyBuffer_Release(&(*buf)[j]);
9434 }
Victor Stinner00d7abd2020-12-01 09:56:42 +01009435 PyMem_Free(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009436 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009437}
9438
9439static void
9440iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9441{
9442 int i;
Victor Stinner00d7abd2020-12-01 09:56:42 +01009443 PyMem_Free(iov);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009444 for (i = 0; i < cnt; i++) {
9445 PyBuffer_Release(&buf[i]);
9446 }
Victor Stinner00d7abd2020-12-01 09:56:42 +01009447 PyMem_Free(buf);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009448}
9449#endif
9450
Larry Hastings2f936352014-08-05 14:04:04 +10009451
Ross Lagerwall7807c352011-03-17 20:20:30 +02009452#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009453/*[clinic input]
9454os.readv -> Py_ssize_t
9455
9456 fd: int
9457 buffers: object
9458 /
9459
9460Read from a file descriptor fd into an iterable of buffers.
9461
9462The buffers should be mutable buffers accepting bytes.
9463readv will transfer data into each buffer until it is full
9464and then move on to the next buffer in the sequence to hold
9465the rest of the data.
9466
9467readv returns the total number of bytes read,
9468which may be less than the total capacity of all the buffers.
9469[clinic start generated code]*/
9470
Larry Hastings2f936352014-08-05 14:04:04 +10009471static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009472os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9473/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009474{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009475 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009476 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009477 struct iovec *iov;
9478 Py_buffer *buf;
9479
Larry Hastings2f936352014-08-05 14:04:04 +10009480 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009481 PyErr_SetString(PyExc_TypeError,
9482 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009483 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009484 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009485
Larry Hastings2f936352014-08-05 14:04:04 +10009486 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009487 if (cnt < 0)
9488 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009489
9490 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9491 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009492
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009493 do {
9494 Py_BEGIN_ALLOW_THREADS
9495 n = readv(fd, iov, cnt);
9496 Py_END_ALLOW_THREADS
9497 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009498
9499 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009500 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009501 if (!async_err)
9502 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009503 return -1;
9504 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009505
Larry Hastings2f936352014-08-05 14:04:04 +10009506 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009507}
Larry Hastings2f936352014-08-05 14:04:04 +10009508#endif /* HAVE_READV */
9509
Ross Lagerwall7807c352011-03-17 20:20:30 +02009510
9511#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009512/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009513os.pread
9514
9515 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009516 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009517 offset: Py_off_t
9518 /
9519
9520Read a number of bytes from a file descriptor starting at a particular offset.
9521
9522Read length bytes from file descriptor fd, starting at offset bytes from
9523the beginning of the file. The file offset remains unchanged.
9524[clinic start generated code]*/
9525
Larry Hastings2f936352014-08-05 14:04:04 +10009526static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009527os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9528/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009529{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009530 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009531 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009532 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009533
Larry Hastings2f936352014-08-05 14:04:04 +10009534 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009535 errno = EINVAL;
9536 return posix_error();
9537 }
Larry Hastings2f936352014-08-05 14:04:04 +10009538 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009539 if (buffer == NULL)
9540 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009541
9542 do {
9543 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009544 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009545 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009546 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009547 Py_END_ALLOW_THREADS
9548 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9549
Ross Lagerwall7807c352011-03-17 20:20:30 +02009550 if (n < 0) {
9551 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009552 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009553 }
Larry Hastings2f936352014-08-05 14:04:04 +10009554 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009555 _PyBytes_Resize(&buffer, n);
9556 return buffer;
9557}
Larry Hastings2f936352014-08-05 14:04:04 +10009558#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009559
Pablo Galindo4defba32018-01-27 16:16:37 +00009560#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9561/*[clinic input]
9562os.preadv -> Py_ssize_t
9563
9564 fd: int
9565 buffers: object
9566 offset: Py_off_t
9567 flags: int = 0
9568 /
9569
9570Reads from a file descriptor into a number of mutable bytes-like objects.
9571
9572Combines the functionality of readv() and pread(). As readv(), it will
9573transfer data into each buffer until it is full and then move on to the next
9574buffer in the sequence to hold the rest of the data. Its fourth argument,
9575specifies the file offset at which the input operation is to be performed. It
9576will return the total number of bytes read (which can be less than the total
9577capacity of all the objects).
9578
9579The flags argument contains a bitwise OR of zero or more of the following flags:
9580
9581- RWF_HIPRI
9582- RWF_NOWAIT
9583
9584Using non-zero flags requires Linux 4.6 or newer.
9585[clinic start generated code]*/
9586
9587static Py_ssize_t
9588os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9589 int flags)
9590/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9591{
9592 Py_ssize_t cnt, n;
9593 int async_err = 0;
9594 struct iovec *iov;
9595 Py_buffer *buf;
9596
9597 if (!PySequence_Check(buffers)) {
9598 PyErr_SetString(PyExc_TypeError,
9599 "preadv2() arg 2 must be a sequence");
9600 return -1;
9601 }
9602
9603 cnt = PySequence_Size(buffers);
9604 if (cnt < 0) {
9605 return -1;
9606 }
9607
9608#ifndef HAVE_PREADV2
9609 if(flags != 0) {
9610 argument_unavailable_error("preadv2", "flags");
9611 return -1;
9612 }
9613#endif
9614
9615 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9616 return -1;
9617 }
9618#ifdef HAVE_PREADV2
9619 do {
9620 Py_BEGIN_ALLOW_THREADS
9621 _Py_BEGIN_SUPPRESS_IPH
9622 n = preadv2(fd, iov, cnt, offset, flags);
9623 _Py_END_SUPPRESS_IPH
9624 Py_END_ALLOW_THREADS
9625 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9626#else
9627 do {
Ronald Oussoren41761932020-11-08 10:05:27 +01009628#ifdef __APPLE__
9629/* This entire function will be removed from the module dict when the API
9630 * is not available.
9631 */
9632#pragma clang diagnostic push
9633#pragma clang diagnostic ignored "-Wunguarded-availability"
9634#pragma clang diagnostic ignored "-Wunguarded-availability-new"
9635#endif
Pablo Galindo4defba32018-01-27 16:16:37 +00009636 Py_BEGIN_ALLOW_THREADS
9637 _Py_BEGIN_SUPPRESS_IPH
9638 n = preadv(fd, iov, cnt, offset);
9639 _Py_END_SUPPRESS_IPH
9640 Py_END_ALLOW_THREADS
9641 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +01009642
9643#ifdef __APPLE__
9644#pragma clang diagnostic pop
9645#endif
9646
Pablo Galindo4defba32018-01-27 16:16:37 +00009647#endif
9648
9649 iov_cleanup(iov, buf, cnt);
9650 if (n < 0) {
9651 if (!async_err) {
9652 posix_error();
9653 }
9654 return -1;
9655 }
9656
9657 return n;
9658}
9659#endif /* HAVE_PREADV */
9660
Larry Hastings2f936352014-08-05 14:04:04 +10009661
9662/*[clinic input]
9663os.write -> Py_ssize_t
9664
9665 fd: int
9666 data: Py_buffer
9667 /
9668
9669Write a bytes object to a file descriptor.
9670[clinic start generated code]*/
9671
Larry Hastings2f936352014-08-05 14:04:04 +10009672static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009673os_write_impl(PyObject *module, int fd, Py_buffer *data)
9674/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009675{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009676 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009677}
9678
9679#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009680#ifdef __APPLE__
9681/*[clinic input]
9682os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009683
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009684 out_fd: int
9685 in_fd: int
9686 offset: Py_off_t
9687 count as sbytes: Py_off_t
9688 headers: object(c_default="NULL") = ()
9689 trailers: object(c_default="NULL") = ()
9690 flags: int = 0
9691
9692Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9693[clinic start generated code]*/
9694
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009695static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009696os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9697 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9698 int flags)
9699/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9700#elif defined(__FreeBSD__) || defined(__DragonFly__)
9701/*[clinic input]
9702os.sendfile
9703
9704 out_fd: int
9705 in_fd: int
9706 offset: Py_off_t
9707 count: Py_ssize_t
9708 headers: object(c_default="NULL") = ()
9709 trailers: object(c_default="NULL") = ()
9710 flags: int = 0
9711
9712Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9713[clinic start generated code]*/
9714
9715static PyObject *
9716os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9717 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9718 int flags)
9719/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9720#else
9721/*[clinic input]
9722os.sendfile
9723
9724 out_fd: int
9725 in_fd: int
9726 offset as offobj: object
9727 count: Py_ssize_t
9728
9729Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9730[clinic start generated code]*/
9731
9732static PyObject *
9733os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9734 Py_ssize_t count)
9735/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9736#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009737{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009738 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009739 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009740
9741#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9742#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009743 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009744#endif
9745 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009746 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009747
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009748 sf.headers = NULL;
9749 sf.trailers = NULL;
9750
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009751 if (headers != NULL) {
9752 if (!PySequence_Check(headers)) {
9753 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009754 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009755 return NULL;
9756 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009757 Py_ssize_t i = PySequence_Size(headers);
9758 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009759 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009760 if (i > INT_MAX) {
9761 PyErr_SetString(PyExc_OverflowError,
9762 "sendfile() header is too large");
9763 return NULL;
9764 }
9765 if (i > 0) {
9766 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009767 if (iov_setup(&(sf.headers), &hbuf,
9768 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009769 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009770#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009771 for (i = 0; i < sf.hdr_cnt; i++) {
9772 Py_ssize_t blen = sf.headers[i].iov_len;
9773# define OFF_T_MAX 0x7fffffffffffffff
9774 if (sbytes >= OFF_T_MAX - blen) {
9775 PyErr_SetString(PyExc_OverflowError,
9776 "sendfile() header is too large");
9777 return NULL;
9778 }
9779 sbytes += blen;
9780 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009781#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009782 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009783 }
9784 }
9785 if (trailers != NULL) {
9786 if (!PySequence_Check(trailers)) {
9787 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009788 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009789 return NULL;
9790 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009791 Py_ssize_t i = PySequence_Size(trailers);
9792 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009793 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009794 if (i > INT_MAX) {
9795 PyErr_SetString(PyExc_OverflowError,
9796 "sendfile() trailer is too large");
9797 return NULL;
9798 }
9799 if (i > 0) {
9800 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009801 if (iov_setup(&(sf.trailers), &tbuf,
9802 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009803 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009804 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009805 }
9806 }
9807
Steve Dower8fc89802015-04-12 00:26:27 -04009808 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009809 do {
9810 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009811#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009812 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009813#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009814 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009815#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009816 Py_END_ALLOW_THREADS
9817 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009818 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009819
9820 if (sf.headers != NULL)
9821 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9822 if (sf.trailers != NULL)
9823 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9824
9825 if (ret < 0) {
9826 if ((errno == EAGAIN) || (errno == EBUSY)) {
9827 if (sbytes != 0) {
9828 // some data has been sent
9829 goto done;
9830 }
9831 else {
9832 // no data has been sent; upper application is supposed
9833 // to retry on EAGAIN or EBUSY
9834 return posix_error();
9835 }
9836 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009837 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009838 }
9839 goto done;
9840
9841done:
9842 #if !defined(HAVE_LARGEFILE_SUPPORT)
9843 return Py_BuildValue("l", sbytes);
9844 #else
9845 return Py_BuildValue("L", sbytes);
9846 #endif
9847
9848#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009849#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009850 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009851 do {
9852 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009853 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009854 Py_END_ALLOW_THREADS
9855 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009856 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009857 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009858 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009859 }
9860#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009861 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009862 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009863 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009864
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009865#if defined(__sun) && defined(__SVR4)
9866 // On Solaris, sendfile raises EINVAL rather than returning 0
9867 // when the offset is equal or bigger than the in_fd size.
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009868 struct stat st;
9869
9870 do {
9871 Py_BEGIN_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009872 ret = fstat(in_fd, &st);
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009873 Py_END_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009874 } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009875 if (ret < 0)
9876 return (!async_err) ? posix_error() : NULL;
9877
9878 if (offset >= st.st_size) {
9879 return Py_BuildValue("i", 0);
9880 }
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009881
9882 // On illumos specifically sendfile() may perform a partial write but
9883 // return -1/an error (in one confirmed case the destination socket
9884 // had a 5 second timeout set and errno was EAGAIN) and it's on the client
9885 // code to check if the offset parameter was modified by sendfile().
9886 //
9887 // We need this variable to track said change.
9888 off_t original_offset = offset;
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009889#endif
9890
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009891 do {
9892 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009893 ret = sendfile(out_fd, in_fd, &offset, count);
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009894#if defined(__sun) && defined(__SVR4)
9895 // This handles illumos-specific sendfile() partial write behavior,
9896 // see a comment above for more details.
9897 if (ret < 0 && offset != original_offset) {
9898 ret = offset - original_offset;
9899 }
9900#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009901 Py_END_ALLOW_THREADS
9902 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009903 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009904 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009905 return Py_BuildValue("n", ret);
9906#endif
9907}
Larry Hastings2f936352014-08-05 14:04:04 +10009908#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009909
Larry Hastings2f936352014-08-05 14:04:04 +10009910
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009911#if defined(__APPLE__)
9912/*[clinic input]
9913os._fcopyfile
9914
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009915 in_fd: int
9916 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009917 flags: int
9918 /
9919
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009920Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009921[clinic start generated code]*/
9922
9923static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009924os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9925/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009926{
9927 int ret;
9928
9929 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009930 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009931 Py_END_ALLOW_THREADS
9932 if (ret < 0)
9933 return posix_error();
9934 Py_RETURN_NONE;
9935}
9936#endif
9937
9938
Larry Hastings2f936352014-08-05 14:04:04 +10009939/*[clinic input]
9940os.fstat
9941
9942 fd : int
9943
9944Perform a stat system call on the given file descriptor.
9945
9946Like stat(), but for an open file descriptor.
9947Equivalent to os.stat(fd).
9948[clinic start generated code]*/
9949
Larry Hastings2f936352014-08-05 14:04:04 +10009950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009951os_fstat_impl(PyObject *module, int fd)
9952/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009953{
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 STRUCT_STAT st;
9955 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009956 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009957
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009958 do {
9959 Py_BEGIN_ALLOW_THREADS
9960 res = FSTAT(fd, &st);
9961 Py_END_ALLOW_THREADS
9962 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009964#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009965 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009966#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009967 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009968#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 }
Tim Peters5aa91602002-01-30 05:46:57 +00009970
Victor Stinner1c2fa782020-05-10 11:05:29 +02009971 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009972}
9973
Larry Hastings2f936352014-08-05 14:04:04 +10009974
9975/*[clinic input]
9976os.isatty -> bool
9977 fd: int
9978 /
9979
9980Return True if the fd is connected to a terminal.
9981
9982Return True if the file descriptor is an open file descriptor
9983connected to the slave end of a terminal.
9984[clinic start generated code]*/
9985
Larry Hastings2f936352014-08-05 14:04:04 +10009986static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009987os_isatty_impl(PyObject *module, int fd)
9988/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009989{
Steve Dower8fc89802015-04-12 00:26:27 -04009990 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009991 _Py_BEGIN_SUPPRESS_IPH
9992 return_value = isatty(fd);
9993 _Py_END_SUPPRESS_IPH
9994 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10009995}
9996
9997
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009998#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10009999/*[clinic input]
10000os.pipe
10001
10002Create a pipe.
10003
10004Returns a tuple of two file descriptors:
10005 (read_fd, write_fd)
10006[clinic start generated code]*/
10007
Larry Hastings2f936352014-08-05 14:04:04 +100010008static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010009os_pipe_impl(PyObject *module)
10010/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +000010011{
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +020010013#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010015 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010017#else
10018 int res;
10019#endif
10020
10021#ifdef MS_WINDOWS
10022 attr.nLength = sizeof(attr);
10023 attr.lpSecurityDescriptor = NULL;
10024 attr.bInheritHandle = FALSE;
10025
10026 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -080010027 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +020010028 ok = CreatePipe(&read, &write, &attr, 0);
10029 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -070010030 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
10031 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010032 if (fds[0] == -1 || fds[1] == -1) {
10033 CloseHandle(read);
10034 CloseHandle(write);
10035 ok = 0;
10036 }
10037 }
Steve Dowerc3630612016-11-19 18:41:16 -080010038 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +020010039 Py_END_ALLOW_THREADS
10040
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +010010042 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010043#else
10044
10045#ifdef HAVE_PIPE2
10046 Py_BEGIN_ALLOW_THREADS
10047 res = pipe2(fds, O_CLOEXEC);
10048 Py_END_ALLOW_THREADS
10049
10050 if (res != 0 && errno == ENOSYS)
10051 {
10052#endif
10053 Py_BEGIN_ALLOW_THREADS
10054 res = pipe(fds);
10055 Py_END_ALLOW_THREADS
10056
10057 if (res == 0) {
10058 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
10059 close(fds[0]);
10060 close(fds[1]);
10061 return NULL;
10062 }
10063 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
10064 close(fds[0]);
10065 close(fds[1]);
10066 return NULL;
10067 }
10068 }
10069#ifdef HAVE_PIPE2
10070 }
10071#endif
10072
10073 if (res != 0)
10074 return PyErr_SetFromErrno(PyExc_OSError);
10075#endif /* !MS_WINDOWS */
10076 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +000010077}
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010078#endif /* HAVE_PIPE */
10079
Larry Hastings2f936352014-08-05 14:04:04 +100010080
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010081#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +100010082/*[clinic input]
10083os.pipe2
10084
10085 flags: int
10086 /
10087
10088Create a pipe with flags set atomically.
10089
10090Returns a tuple of two file descriptors:
10091 (read_fd, write_fd)
10092
10093flags can be constructed by ORing together one or more of these values:
10094O_NONBLOCK, O_CLOEXEC.
10095[clinic start generated code]*/
10096
Larry Hastings2f936352014-08-05 14:04:04 +100010097static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010098os_pipe2_impl(PyObject *module, int flags)
10099/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010100{
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010101 int fds[2];
10102 int res;
10103
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010104 res = pipe2(fds, flags);
10105 if (res != 0)
10106 return posix_error();
10107 return Py_BuildValue("(ii)", fds[0], fds[1]);
10108}
10109#endif /* HAVE_PIPE2 */
10110
Larry Hastings2f936352014-08-05 14:04:04 +100010111
Ross Lagerwall7807c352011-03-17 20:20:30 +020010112#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +100010113/*[clinic input]
10114os.writev -> Py_ssize_t
10115 fd: int
10116 buffers: object
10117 /
10118
10119Iterate over buffers, and write the contents of each to a file descriptor.
10120
10121Returns the total number of bytes written.
10122buffers must be a sequence of bytes-like objects.
10123[clinic start generated code]*/
10124
Larry Hastings2f936352014-08-05 14:04:04 +100010125static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010126os_writev_impl(PyObject *module, int fd, PyObject *buffers)
10127/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010128{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010129 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +100010130 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010131 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010132 struct iovec *iov;
10133 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +100010134
10135 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020010136 PyErr_SetString(PyExc_TypeError,
10137 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +100010138 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010139 }
Larry Hastings2f936352014-08-05 14:04:04 +100010140 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010141 if (cnt < 0)
10142 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010143
Larry Hastings2f936352014-08-05 14:04:04 +100010144 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10145 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010146 }
10147
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010148 do {
10149 Py_BEGIN_ALLOW_THREADS
10150 result = writev(fd, iov, cnt);
10151 Py_END_ALLOW_THREADS
10152 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +020010153
10154 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010155 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010156 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +010010157
Georg Brandl306336b2012-06-24 12:55:33 +020010158 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010159}
Larry Hastings2f936352014-08-05 14:04:04 +100010160#endif /* HAVE_WRITEV */
10161
10162
10163#ifdef HAVE_PWRITE
10164/*[clinic input]
10165os.pwrite -> Py_ssize_t
10166
10167 fd: int
10168 buffer: Py_buffer
10169 offset: Py_off_t
10170 /
10171
10172Write bytes to a file descriptor starting at a particular offset.
10173
10174Write buffer to fd, starting at offset bytes from the beginning of
10175the file. Returns the number of bytes writte. Does not change the
10176current file offset.
10177[clinic start generated code]*/
10178
Larry Hastings2f936352014-08-05 14:04:04 +100010179static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010180os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
10181/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010182{
10183 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010184 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010185
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010186 do {
10187 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -040010188 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010189 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -040010190 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010191 Py_END_ALLOW_THREADS
10192 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010193
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010194 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010195 posix_error();
10196 return size;
10197}
10198#endif /* HAVE_PWRITE */
10199
Pablo Galindo4defba32018-01-27 16:16:37 +000010200#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
10201/*[clinic input]
10202os.pwritev -> Py_ssize_t
10203
10204 fd: int
10205 buffers: object
10206 offset: Py_off_t
10207 flags: int = 0
10208 /
10209
10210Writes the contents of bytes-like objects to a file descriptor at a given offset.
10211
10212Combines the functionality of writev() and pwrite(). All buffers must be a sequence
10213of bytes-like objects. Buffers are processed in array order. Entire contents of first
10214buffer is written before proceeding to second, and so on. The operating system may
10215set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
10216This function writes the contents of each object to the file descriptor and returns
10217the total number of bytes written.
10218
10219The flags argument contains a bitwise OR of zero or more of the following flags:
10220
10221- RWF_DSYNC
10222- RWF_SYNC
YoSTEALTH76ef2552020-05-27 15:32:22 -060010223- RWF_APPEND
Pablo Galindo4defba32018-01-27 16:16:37 +000010224
10225Using non-zero flags requires Linux 4.7 or newer.
10226[clinic start generated code]*/
10227
10228static Py_ssize_t
10229os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
10230 int flags)
YoSTEALTH76ef2552020-05-27 15:32:22 -060010231/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/
Pablo Galindo4defba32018-01-27 16:16:37 +000010232{
10233 Py_ssize_t cnt;
10234 Py_ssize_t result;
10235 int async_err = 0;
10236 struct iovec *iov;
10237 Py_buffer *buf;
10238
10239 if (!PySequence_Check(buffers)) {
10240 PyErr_SetString(PyExc_TypeError,
10241 "pwritev() arg 2 must be a sequence");
10242 return -1;
10243 }
10244
10245 cnt = PySequence_Size(buffers);
10246 if (cnt < 0) {
10247 return -1;
10248 }
10249
10250#ifndef HAVE_PWRITEV2
10251 if(flags != 0) {
10252 argument_unavailable_error("pwritev2", "flags");
10253 return -1;
10254 }
10255#endif
10256
10257 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10258 return -1;
10259 }
10260#ifdef HAVE_PWRITEV2
10261 do {
10262 Py_BEGIN_ALLOW_THREADS
10263 _Py_BEGIN_SUPPRESS_IPH
10264 result = pwritev2(fd, iov, cnt, offset, flags);
10265 _Py_END_SUPPRESS_IPH
10266 Py_END_ALLOW_THREADS
10267 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10268#else
Ronald Oussoren41761932020-11-08 10:05:27 +010010269
10270#ifdef __APPLE__
10271/* This entire function will be removed from the module dict when the API
10272 * is not available.
10273 */
10274#pragma clang diagnostic push
10275#pragma clang diagnostic ignored "-Wunguarded-availability"
10276#pragma clang diagnostic ignored "-Wunguarded-availability-new"
10277#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000010278 do {
10279 Py_BEGIN_ALLOW_THREADS
10280 _Py_BEGIN_SUPPRESS_IPH
10281 result = pwritev(fd, iov, cnt, offset);
10282 _Py_END_SUPPRESS_IPH
10283 Py_END_ALLOW_THREADS
10284 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +010010285
10286#ifdef __APPLE__
10287#pragma clang diagnostic pop
10288#endif
10289
Pablo Galindo4defba32018-01-27 16:16:37 +000010290#endif
10291
10292 iov_cleanup(iov, buf, cnt);
10293 if (result < 0) {
10294 if (!async_err) {
10295 posix_error();
10296 }
10297 return -1;
10298 }
10299
10300 return result;
10301}
10302#endif /* HAVE_PWRITEV */
10303
Pablo Galindoaac4d032019-05-31 19:39:47 +010010304#ifdef HAVE_COPY_FILE_RANGE
10305/*[clinic input]
10306
10307os.copy_file_range
10308 src: int
10309 Source file descriptor.
10310 dst: int
10311 Destination file descriptor.
10312 count: Py_ssize_t
10313 Number of bytes to copy.
10314 offset_src: object = None
10315 Starting offset in src.
10316 offset_dst: object = None
10317 Starting offset in dst.
10318
10319Copy count bytes from one file descriptor to another.
10320
10321If offset_src is None, then src is read from the current position;
10322respectively for offset_dst.
10323[clinic start generated code]*/
10324
10325static PyObject *
10326os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10327 PyObject *offset_src, PyObject *offset_dst)
10328/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
10329{
10330 off_t offset_src_val, offset_dst_val;
10331 off_t *p_offset_src = NULL;
10332 off_t *p_offset_dst = NULL;
10333 Py_ssize_t ret;
10334 int async_err = 0;
10335 /* The flags argument is provided to allow
10336 * for future extensions and currently must be to 0. */
10337 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +000010338
10339
Pablo Galindoaac4d032019-05-31 19:39:47 +010010340 if (count < 0) {
10341 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10342 return NULL;
10343 }
10344
10345 if (offset_src != Py_None) {
10346 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10347 return NULL;
10348 }
10349 p_offset_src = &offset_src_val;
10350 }
10351
10352 if (offset_dst != Py_None) {
10353 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10354 return NULL;
10355 }
10356 p_offset_dst = &offset_dst_val;
10357 }
10358
10359 do {
10360 Py_BEGIN_ALLOW_THREADS
10361 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
10362 Py_END_ALLOW_THREADS
10363 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10364
10365 if (ret < 0) {
10366 return (!async_err) ? posix_error() : NULL;
10367 }
10368
10369 return PyLong_FromSsize_t(ret);
10370}
10371#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +100010372
Pablo Galindodedc2cd2020-12-02 17:57:18 +000010373#if (defined(HAVE_SPLICE) && !defined(_AIX))
Pablo Galindoa57b3d32020-11-17 00:00:38 +000010374/*[clinic input]
10375
10376os.splice
10377 src: int
10378 Source file descriptor.
10379 dst: int
10380 Destination file descriptor.
10381 count: Py_ssize_t
10382 Number of bytes to copy.
10383 offset_src: object = None
10384 Starting offset in src.
10385 offset_dst: object = None
10386 Starting offset in dst.
10387 flags: unsigned_int = 0
10388 Flags to modify the semantics of the call.
10389
10390Transfer count bytes from one pipe to a descriptor or vice versa.
10391
10392If offset_src is None, then src is read from the current position;
10393respectively for offset_dst. The offset associated to the file
10394descriptor that refers to a pipe must be None.
10395[clinic start generated code]*/
10396
10397static PyObject *
10398os_splice_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10399 PyObject *offset_src, PyObject *offset_dst,
10400 unsigned int flags)
10401/*[clinic end generated code: output=d0386f25a8519dc5 input=047527c66c6d2e0a]*/
10402{
10403 off_t offset_src_val, offset_dst_val;
10404 off_t *p_offset_src = NULL;
10405 off_t *p_offset_dst = NULL;
10406 Py_ssize_t ret;
10407 int async_err = 0;
10408
10409 if (count < 0) {
10410 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10411 return NULL;
10412 }
10413
10414 if (offset_src != Py_None) {
10415 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10416 return NULL;
10417 }
10418 p_offset_src = &offset_src_val;
10419 }
10420
10421 if (offset_dst != Py_None) {
10422 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10423 return NULL;
10424 }
10425 p_offset_dst = &offset_dst_val;
10426 }
10427
10428 do {
10429 Py_BEGIN_ALLOW_THREADS
10430 ret = splice(src, p_offset_src, dst, p_offset_dst, count, flags);
10431 Py_END_ALLOW_THREADS
10432 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10433
10434 if (ret < 0) {
10435 return (!async_err) ? posix_error() : NULL;
10436 }
10437
10438 return PyLong_FromSsize_t(ret);
10439}
10440#endif /* HAVE_SPLICE*/
10441
Larry Hastings2f936352014-08-05 14:04:04 +100010442#ifdef HAVE_MKFIFO
10443/*[clinic input]
10444os.mkfifo
10445
10446 path: path_t
10447 mode: int=0o666
10448 *
10449 dir_fd: dir_fd(requires='mkfifoat')=None
10450
10451Create a "fifo" (a POSIX named pipe).
10452
10453If dir_fd is not None, it should be a file descriptor open to a directory,
10454 and path should be relative; path will then be relative to that directory.
10455dir_fd may not be implemented on your platform.
10456 If it is unavailable, using it will raise a NotImplementedError.
10457[clinic start generated code]*/
10458
Larry Hastings2f936352014-08-05 14:04:04 +100010459static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010460os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
10461/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010462{
10463 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010464 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010465
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010466 do {
10467 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010468#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010469 if (dir_fd != DEFAULT_DIR_FD)
10470 result = mkfifoat(dir_fd, path->narrow, mode);
10471 else
Ross Lagerwall7807c352011-03-17 20:20:30 +020010472#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010473 result = mkfifo(path->narrow, mode);
10474 Py_END_ALLOW_THREADS
10475 } while (result != 0 && errno == EINTR &&
10476 !(async_err = PyErr_CheckSignals()));
10477 if (result != 0)
10478 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010479
10480 Py_RETURN_NONE;
10481}
10482#endif /* HAVE_MKFIFO */
10483
10484
10485#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
10486/*[clinic input]
10487os.mknod
10488
10489 path: path_t
10490 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010491 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +100010492 *
10493 dir_fd: dir_fd(requires='mknodat')=None
10494
10495Create a node in the file system.
10496
10497Create a node in the file system (file, device special file or named pipe)
10498at path. mode specifies both the permissions to use and the
10499type of node to be created, being combined (bitwise OR) with one of
10500S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
10501device defines the newly created device special file (probably using
10502os.makedev()). Otherwise device is ignored.
10503
10504If dir_fd is not None, it should be a file descriptor open to a directory,
10505 and path should be relative; path will then be relative to that directory.
10506dir_fd may not be implemented on your platform.
10507 If it is unavailable, using it will raise a NotImplementedError.
10508[clinic start generated code]*/
10509
Larry Hastings2f936352014-08-05 14:04:04 +100010510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010511os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -040010512 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010513/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010514{
10515 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010516 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010517
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010518 do {
10519 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010520#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010521 if (dir_fd != DEFAULT_DIR_FD)
10522 result = mknodat(dir_fd, path->narrow, mode, device);
10523 else
Larry Hastings2f936352014-08-05 14:04:04 +100010524#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010525 result = mknod(path->narrow, mode, device);
10526 Py_END_ALLOW_THREADS
10527 } while (result != 0 && errno == EINTR &&
10528 !(async_err = PyErr_CheckSignals()));
10529 if (result != 0)
10530 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010531
10532 Py_RETURN_NONE;
10533}
10534#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10535
10536
10537#ifdef HAVE_DEVICE_MACROS
10538/*[clinic input]
10539os.major -> unsigned_int
10540
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010541 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010542 /
10543
10544Extracts a device major number from a raw device number.
10545[clinic start generated code]*/
10546
Larry Hastings2f936352014-08-05 14:04:04 +100010547static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010548os_major_impl(PyObject *module, dev_t device)
10549/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010550{
10551 return major(device);
10552}
10553
10554
10555/*[clinic input]
10556os.minor -> unsigned_int
10557
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010558 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010559 /
10560
10561Extracts a device minor number from a raw device number.
10562[clinic start generated code]*/
10563
Larry Hastings2f936352014-08-05 14:04:04 +100010564static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010565os_minor_impl(PyObject *module, dev_t device)
10566/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010567{
10568 return minor(device);
10569}
10570
10571
10572/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010573os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010574
10575 major: int
10576 minor: int
10577 /
10578
10579Composes a raw device number from the major and minor device numbers.
10580[clinic start generated code]*/
10581
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010582static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010583os_makedev_impl(PyObject *module, int major, int minor)
10584/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010585{
10586 return makedev(major, minor);
10587}
10588#endif /* HAVE_DEVICE_MACROS */
10589
10590
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010591#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010592/*[clinic input]
10593os.ftruncate
10594
10595 fd: int
10596 length: Py_off_t
10597 /
10598
10599Truncate a file, specified by file descriptor, to a specific length.
10600[clinic start generated code]*/
10601
Larry Hastings2f936352014-08-05 14:04:04 +100010602static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010603os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10604/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010605{
10606 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010607 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010608
Steve Dowerb82e17e2019-05-23 08:45:22 -070010609 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10610 return NULL;
10611 }
10612
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010613 do {
10614 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010615 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010616#ifdef MS_WINDOWS
10617 result = _chsize_s(fd, length);
10618#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010619 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010620#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010621 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010622 Py_END_ALLOW_THREADS
10623 } while (result != 0 && errno == EINTR &&
10624 !(async_err = PyErr_CheckSignals()));
10625 if (result != 0)
10626 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010627 Py_RETURN_NONE;
10628}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010629#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010630
10631
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010632#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010633/*[clinic input]
10634os.truncate
10635 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10636 length: Py_off_t
10637
10638Truncate a file, specified by path, to a specific length.
10639
10640On some platforms, path may also be specified as an open file descriptor.
10641 If this functionality is unavailable, using it raises an exception.
10642[clinic start generated code]*/
10643
Larry Hastings2f936352014-08-05 14:04:04 +100010644static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010645os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10646/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010647{
10648 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010649#ifdef MS_WINDOWS
10650 int fd;
10651#endif
10652
10653 if (path->fd != -1)
10654 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010655
Steve Dowerb82e17e2019-05-23 08:45:22 -070010656 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10657 return NULL;
10658 }
10659
Larry Hastings2f936352014-08-05 14:04:04 +100010660 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010661 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010662#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010663 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010664 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010665 result = -1;
10666 else {
10667 result = _chsize_s(fd, length);
10668 close(fd);
10669 if (result < 0)
10670 errno = result;
10671 }
10672#else
10673 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010674#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010675 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010676 Py_END_ALLOW_THREADS
10677 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010678 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010679
10680 Py_RETURN_NONE;
10681}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010682#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010683
Ross Lagerwall7807c352011-03-17 20:20:30 +020010684
Victor Stinnerd6b17692014-09-30 12:20:05 +020010685/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10686 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10687 defined, which is the case in Python on AIX. AIX bug report:
10688 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10689#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10690# define POSIX_FADVISE_AIX_BUG
10691#endif
10692
Victor Stinnerec39e262014-09-30 12:35:58 +020010693
Victor Stinnerd6b17692014-09-30 12:20:05 +020010694#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010695/*[clinic input]
10696os.posix_fallocate
10697
10698 fd: int
10699 offset: Py_off_t
10700 length: Py_off_t
10701 /
10702
10703Ensure a file has allocated at least a particular number of bytes on disk.
10704
10705Ensure that the file specified by fd encompasses a range of bytes
10706starting at offset bytes from the beginning and continuing for length bytes.
10707[clinic start generated code]*/
10708
Larry Hastings2f936352014-08-05 14:04:04 +100010709static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010710os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010711 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010712/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010713{
10714 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010715 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010716
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010717 do {
10718 Py_BEGIN_ALLOW_THREADS
10719 result = posix_fallocate(fd, offset, length);
10720 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010721 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10722
10723 if (result == 0)
10724 Py_RETURN_NONE;
10725
10726 if (async_err)
10727 return NULL;
10728
10729 errno = result;
10730 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010731}
Victor Stinnerec39e262014-09-30 12:35:58 +020010732#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010733
Ross Lagerwall7807c352011-03-17 20:20:30 +020010734
Victor Stinnerd6b17692014-09-30 12:20:05 +020010735#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010736/*[clinic input]
10737os.posix_fadvise
10738
10739 fd: int
10740 offset: Py_off_t
10741 length: Py_off_t
10742 advice: int
10743 /
10744
10745Announce an intention to access data in a specific pattern.
10746
10747Announce an intention to access data in a specific pattern, thus allowing
10748the kernel to make optimizations.
10749The advice applies to the region of the file specified by fd starting at
10750offset and continuing for length bytes.
10751advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10752POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10753POSIX_FADV_DONTNEED.
10754[clinic start generated code]*/
10755
Larry Hastings2f936352014-08-05 14:04:04 +100010756static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010757os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010758 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010759/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010760{
10761 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010762 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010763
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010764 do {
10765 Py_BEGIN_ALLOW_THREADS
10766 result = posix_fadvise(fd, offset, length, advice);
10767 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010768 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10769
10770 if (result == 0)
10771 Py_RETURN_NONE;
10772
10773 if (async_err)
10774 return NULL;
10775
10776 errno = result;
10777 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010778}
Victor Stinnerec39e262014-09-30 12:35:58 +020010779#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010781
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010782#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010783static PyObject*
10784win32_putenv(PyObject *name, PyObject *value)
10785{
10786 /* Search from index 1 because on Windows starting '=' is allowed for
10787 defining hidden environment variables. */
10788 if (PyUnicode_GET_LENGTH(name) == 0 ||
10789 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10790 {
10791 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10792 return NULL;
10793 }
10794 PyObject *unicode;
10795 if (value != NULL) {
10796 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10797 }
10798 else {
10799 unicode = PyUnicode_FromFormat("%U=", name);
10800 }
10801 if (unicode == NULL) {
10802 return NULL;
10803 }
10804
10805 Py_ssize_t size;
10806 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10807 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10808 Py_DECREF(unicode);
10809
10810 if (env == NULL) {
10811 return NULL;
10812 }
10813 if (size > _MAX_ENV) {
10814 PyErr_Format(PyExc_ValueError,
10815 "the environment variable is longer than %u characters",
10816 _MAX_ENV);
10817 PyMem_Free(env);
10818 return NULL;
10819 }
10820
10821 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10822 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10823 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10824
10825 Prefer _wputenv() to be compatible with C libraries using CRT
10826 variables and CRT functions using these variables (ex: getenv()). */
10827 int err = _wputenv(env);
10828 PyMem_Free(env);
10829
10830 if (err) {
10831 posix_error();
10832 return NULL;
10833 }
10834
10835 Py_RETURN_NONE;
10836}
10837#endif
10838
10839
10840#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010841/*[clinic input]
10842os.putenv
10843
10844 name: unicode
10845 value: unicode
10846 /
10847
10848Change or add an environment variable.
10849[clinic start generated code]*/
10850
Larry Hastings2f936352014-08-05 14:04:04 +100010851static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010852os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10853/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010854{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010855 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10856 return NULL;
10857 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010858 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010859}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010860#else
Larry Hastings2f936352014-08-05 14:04:04 +100010861/*[clinic input]
10862os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010863
Larry Hastings2f936352014-08-05 14:04:04 +100010864 name: FSConverter
10865 value: FSConverter
10866 /
10867
10868Change or add an environment variable.
10869[clinic start generated code]*/
10870
Larry Hastings2f936352014-08-05 14:04:04 +100010871static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010872os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10873/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010874{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010875 const char *name_string = PyBytes_AS_STRING(name);
10876 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010877
Serhiy Storchaka77703942017-06-25 07:33:01 +030010878 if (strchr(name_string, '=') != NULL) {
10879 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10880 return NULL;
10881 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010882
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010883 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10884 return NULL;
10885 }
10886
Victor Stinnerb477d192020-01-22 22:48:16 +010010887 if (setenv(name_string, value_string, 1)) {
10888 return posix_error();
10889 }
Larry Hastings2f936352014-08-05 14:04:04 +100010890 Py_RETURN_NONE;
10891}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010892#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010893
10894
Victor Stinner161e7b32020-01-24 11:53:44 +010010895#ifdef MS_WINDOWS
10896/*[clinic input]
10897os.unsetenv
10898 name: unicode
10899 /
10900
10901Delete an environment variable.
10902[clinic start generated code]*/
10903
10904static PyObject *
10905os_unsetenv_impl(PyObject *module, PyObject *name)
10906/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10907{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010908 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10909 return NULL;
10910 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010911 return win32_putenv(name, NULL);
10912}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010913#else
Larry Hastings2f936352014-08-05 14:04:04 +100010914/*[clinic input]
10915os.unsetenv
10916 name: FSConverter
10917 /
10918
10919Delete an environment variable.
10920[clinic start generated code]*/
10921
Larry Hastings2f936352014-08-05 14:04:04 +100010922static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010923os_unsetenv_impl(PyObject *module, PyObject *name)
10924/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010925{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010926 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10927 return NULL;
10928 }
Victor Stinner984890f2011-11-24 13:53:38 +010010929#ifdef HAVE_BROKEN_UNSETENV
10930 unsetenv(PyBytes_AS_STRING(name));
10931#else
Victor Stinner161e7b32020-01-24 11:53:44 +010010932 int err = unsetenv(PyBytes_AS_STRING(name));
10933 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010010934 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010010935 }
Victor Stinner984890f2011-11-24 13:53:38 +010010936#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010937
Victor Stinner84ae1182010-05-06 22:05:07 +000010938 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010939}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010940#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000010941
Larry Hastings2f936352014-08-05 14:04:04 +100010942
10943/*[clinic input]
10944os.strerror
10945
10946 code: int
10947 /
10948
10949Translate an error code to a message string.
10950[clinic start generated code]*/
10951
Larry Hastings2f936352014-08-05 14:04:04 +100010952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010953os_strerror_impl(PyObject *module, int code)
10954/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010955{
10956 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 if (message == NULL) {
10958 PyErr_SetString(PyExc_ValueError,
10959 "strerror() argument out of range");
10960 return NULL;
10961 }
Victor Stinner1b579672011-12-17 05:47:23 +010010962 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010963}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010964
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010965
Guido van Rossumc9641791998-08-04 15:26:23 +000010966#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010967#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010968/*[clinic input]
10969os.WCOREDUMP -> bool
10970
10971 status: int
10972 /
10973
10974Return True if the process returning status was dumped to a core file.
10975[clinic start generated code]*/
10976
Larry Hastings2f936352014-08-05 14:04:04 +100010977static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010978os_WCOREDUMP_impl(PyObject *module, int status)
10979/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010980{
10981 WAIT_TYPE wait_status;
10982 WAIT_STATUS_INT(wait_status) = status;
10983 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010984}
10985#endif /* WCOREDUMP */
10986
Larry Hastings2f936352014-08-05 14:04:04 +100010987
Fred Drake106c1a02002-04-23 15:58:02 +000010988#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010989/*[clinic input]
10990os.WIFCONTINUED -> bool
10991
10992 status: int
10993
10994Return True if a particular process was continued from a job control stop.
10995
10996Return True if the process returning status was continued from a
10997job control stop.
10998[clinic start generated code]*/
10999
Larry Hastings2f936352014-08-05 14:04:04 +100011000static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011001os_WIFCONTINUED_impl(PyObject *module, int status)
11002/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011003{
11004 WAIT_TYPE wait_status;
11005 WAIT_STATUS_INT(wait_status) = status;
11006 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000011007}
11008#endif /* WIFCONTINUED */
11009
Larry Hastings2f936352014-08-05 14:04:04 +100011010
Guido van Rossumc9641791998-08-04 15:26:23 +000011011#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100011012/*[clinic input]
11013os.WIFSTOPPED -> bool
11014
11015 status: int
11016
11017Return True if the process returning status was stopped.
11018[clinic start generated code]*/
11019
Larry Hastings2f936352014-08-05 14:04:04 +100011020static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011021os_WIFSTOPPED_impl(PyObject *module, int status)
11022/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011023{
11024 WAIT_TYPE wait_status;
11025 WAIT_STATUS_INT(wait_status) = status;
11026 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011027}
11028#endif /* WIFSTOPPED */
11029
Larry Hastings2f936352014-08-05 14:04:04 +100011030
Guido van Rossumc9641791998-08-04 15:26:23 +000011031#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100011032/*[clinic input]
11033os.WIFSIGNALED -> bool
11034
11035 status: int
11036
11037Return True if the process returning status was terminated by a signal.
11038[clinic start generated code]*/
11039
Larry Hastings2f936352014-08-05 14:04:04 +100011040static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011041os_WIFSIGNALED_impl(PyObject *module, int status)
11042/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011043{
11044 WAIT_TYPE wait_status;
11045 WAIT_STATUS_INT(wait_status) = status;
11046 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011047}
11048#endif /* WIFSIGNALED */
11049
Larry Hastings2f936352014-08-05 14:04:04 +100011050
Guido van Rossumc9641791998-08-04 15:26:23 +000011051#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100011052/*[clinic input]
11053os.WIFEXITED -> bool
11054
11055 status: int
11056
11057Return True if the process returning status exited via the exit() system call.
11058[clinic start generated code]*/
11059
Larry Hastings2f936352014-08-05 14:04:04 +100011060static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011061os_WIFEXITED_impl(PyObject *module, int status)
11062/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011063{
11064 WAIT_TYPE wait_status;
11065 WAIT_STATUS_INT(wait_status) = status;
11066 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011067}
11068#endif /* WIFEXITED */
11069
Larry Hastings2f936352014-08-05 14:04:04 +100011070
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000011071#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100011072/*[clinic input]
11073os.WEXITSTATUS -> int
11074
11075 status: int
11076
11077Return the process return code from status.
11078[clinic start generated code]*/
11079
Larry Hastings2f936352014-08-05 14:04:04 +100011080static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011081os_WEXITSTATUS_impl(PyObject *module, int status)
11082/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011083{
11084 WAIT_TYPE wait_status;
11085 WAIT_STATUS_INT(wait_status) = status;
11086 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011087}
11088#endif /* WEXITSTATUS */
11089
Larry Hastings2f936352014-08-05 14:04:04 +100011090
Guido van Rossumc9641791998-08-04 15:26:23 +000011091#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011092/*[clinic input]
11093os.WTERMSIG -> int
11094
11095 status: int
11096
11097Return the signal that terminated the process that provided the status value.
11098[clinic start generated code]*/
11099
Larry Hastings2f936352014-08-05 14:04:04 +100011100static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011101os_WTERMSIG_impl(PyObject *module, int status)
11102/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011103{
11104 WAIT_TYPE wait_status;
11105 WAIT_STATUS_INT(wait_status) = status;
11106 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011107}
11108#endif /* WTERMSIG */
11109
Larry Hastings2f936352014-08-05 14:04:04 +100011110
Guido van Rossumc9641791998-08-04 15:26:23 +000011111#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011112/*[clinic input]
11113os.WSTOPSIG -> int
11114
11115 status: int
11116
11117Return the signal that stopped the process that provided the status value.
11118[clinic start generated code]*/
11119
Larry Hastings2f936352014-08-05 14:04:04 +100011120static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011121os_WSTOPSIG_impl(PyObject *module, int status)
11122/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011123{
11124 WAIT_TYPE wait_status;
11125 WAIT_STATUS_INT(wait_status) = status;
11126 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011127}
11128#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000011129#endif /* HAVE_SYS_WAIT_H */
11130
11131
Thomas Wouters477c8d52006-05-27 19:21:47 +000011132#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000011133#ifdef _SCO_DS
11134/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
11135 needed definitions in sys/statvfs.h */
11136#define _SVID3
11137#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011138#include <sys/statvfs.h>
11139
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011140static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020011141_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
11142 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080011143 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011144 if (v == NULL)
11145 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011146
11147#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11149 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11150 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
11151 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
11152 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
11153 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
11154 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
11155 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
11156 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11157 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011158#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011159 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11160 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11161 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011162 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011164 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011165 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011166 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011168 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011170 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011171 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011172 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11174 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011175#endif
Michael Felt502d5512018-01-05 13:01:58 +010011176/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
11177 * (issue #32390). */
11178#if defined(_AIX) && defined(_ALL_SOURCE)
11179 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
11180#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010011181 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010011182#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010011183 if (PyErr_Occurred()) {
11184 Py_DECREF(v);
11185 return NULL;
11186 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011187
Victor Stinner8c62be82010-05-06 00:08:46 +000011188 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011189}
11190
Larry Hastings2f936352014-08-05 14:04:04 +100011191
11192/*[clinic input]
11193os.fstatvfs
11194 fd: int
11195 /
11196
11197Perform an fstatvfs system call on the given fd.
11198
11199Equivalent to statvfs(fd).
11200[clinic start generated code]*/
11201
Larry Hastings2f936352014-08-05 14:04:04 +100011202static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011203os_fstatvfs_impl(PyObject *module, int fd)
11204/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011205{
11206 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011207 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011208 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011209
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011210 do {
11211 Py_BEGIN_ALLOW_THREADS
11212 result = fstatvfs(fd, &st);
11213 Py_END_ALLOW_THREADS
11214 } while (result != 0 && errno == EINTR &&
11215 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100011216 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011217 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011218
Victor Stinner1c2fa782020-05-10 11:05:29 +020011219 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011220}
Larry Hastings2f936352014-08-05 14:04:04 +100011221#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000011222
11223
Thomas Wouters477c8d52006-05-27 19:21:47 +000011224#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000011225#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100011226/*[clinic input]
11227os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000011228
Larry Hastings2f936352014-08-05 14:04:04 +100011229 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
11230
11231Perform a statvfs system call on the given path.
11232
11233path may always be specified as a string.
11234On some platforms, path may also be specified as an open file descriptor.
11235 If this functionality is unavailable, using it raises an exception.
11236[clinic start generated code]*/
11237
Larry Hastings2f936352014-08-05 14:04:04 +100011238static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011239os_statvfs_impl(PyObject *module, path_t *path)
11240/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011241{
11242 int result;
11243 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011244
11245 Py_BEGIN_ALLOW_THREADS
11246#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100011247 if (path->fd != -1) {
Larry Hastings2f936352014-08-05 14:04:04 +100011248 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011249 }
11250 else
11251#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011252 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011253 Py_END_ALLOW_THREADS
11254
11255 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011256 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011257 }
11258
Victor Stinner1c2fa782020-05-10 11:05:29 +020011259 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011260}
Larry Hastings2f936352014-08-05 14:04:04 +100011261#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
11262
Guido van Rossum94f6f721999-01-06 18:42:14 +000011263
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011264#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011265/*[clinic input]
11266os._getdiskusage
11267
Steve Dower23ad6d02018-02-22 10:39:10 -080011268 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100011269
11270Return disk usage statistics about the given path as a (total, free) tuple.
11271[clinic start generated code]*/
11272
Larry Hastings2f936352014-08-05 14:04:04 +100011273static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080011274os__getdiskusage_impl(PyObject *module, path_t *path)
11275/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011276{
11277 BOOL retval;
11278 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040011279 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011280
11281 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080011282 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011283 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040011284 if (retval == 0) {
11285 if (GetLastError() == ERROR_DIRECTORY) {
11286 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011287
Joe Pamerc8c02492018-09-25 10:57:36 -040011288 dir_path = PyMem_New(wchar_t, path->length + 1);
11289 if (dir_path == NULL) {
11290 return PyErr_NoMemory();
11291 }
11292
11293 wcscpy_s(dir_path, path->length + 1, path->wide);
11294
11295 if (_dirnameW(dir_path) != -1) {
11296 Py_BEGIN_ALLOW_THREADS
11297 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
11298 Py_END_ALLOW_THREADS
11299 }
11300 /* Record the last error in case it's modified by PyMem_Free. */
11301 err = GetLastError();
11302 PyMem_Free(dir_path);
11303 if (retval) {
11304 goto success;
11305 }
11306 }
11307 return PyErr_SetFromWindowsErr(err);
11308 }
11309
11310success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011311 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
11312}
Larry Hastings2f936352014-08-05 14:04:04 +100011313#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011314
11315
Fred Drakec9680921999-12-13 16:37:25 +000011316/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
11317 * It maps strings representing configuration variable names to
11318 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000011319 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000011320 * rarely-used constants. There are three separate tables that use
11321 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000011322 *
11323 * This code is always included, even if none of the interfaces that
11324 * need it are included. The #if hackery needed to avoid it would be
11325 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000011326 */
11327struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011328 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011329 int value;
Fred Drakec9680921999-12-13 16:37:25 +000011330};
11331
Fred Drake12c6e2d1999-12-14 21:25:03 +000011332static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011333conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000011334 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000011335{
Christian Heimes217cfd12007-12-02 14:31:20 +000011336 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011337 int value = _PyLong_AsInt(arg);
11338 if (value == -1 && PyErr_Occurred())
11339 return 0;
11340 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000011341 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000011342 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000011343 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000011344 /* look up the value in the table using a binary search */
11345 size_t lo = 0;
11346 size_t mid;
11347 size_t hi = tablesize;
11348 int cmp;
11349 const char *confname;
11350 if (!PyUnicode_Check(arg)) {
11351 PyErr_SetString(PyExc_TypeError,
11352 "configuration names must be strings or integers");
11353 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020011355 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000011356 if (confname == NULL)
11357 return 0;
11358 while (lo < hi) {
11359 mid = (lo + hi) / 2;
11360 cmp = strcmp(confname, table[mid].name);
11361 if (cmp < 0)
11362 hi = mid;
11363 else if (cmp > 0)
11364 lo = mid + 1;
11365 else {
11366 *valuep = table[mid].value;
11367 return 1;
11368 }
11369 }
11370 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
11371 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000011373}
11374
11375
11376#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
11377static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011378#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011380#endif
11381#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011382 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011383#endif
Fred Drakec9680921999-12-13 16:37:25 +000011384#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011386#endif
11387#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000011388 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000011389#endif
11390#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000011392#endif
11393#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000011395#endif
11396#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011397 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011398#endif
11399#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000011400 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000011401#endif
11402#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011403 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000011404#endif
11405#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011407#endif
11408#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011409 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000011410#endif
11411#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011412 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011413#endif
11414#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011415 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000011416#endif
11417#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011418 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011419#endif
11420#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011421 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000011422#endif
11423#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011425#endif
11426#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000011428#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000011429#ifdef _PC_ACL_ENABLED
11430 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
11431#endif
11432#ifdef _PC_MIN_HOLE_SIZE
11433 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
11434#endif
11435#ifdef _PC_ALLOC_SIZE_MIN
11436 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
11437#endif
11438#ifdef _PC_REC_INCR_XFER_SIZE
11439 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
11440#endif
11441#ifdef _PC_REC_MAX_XFER_SIZE
11442 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
11443#endif
11444#ifdef _PC_REC_MIN_XFER_SIZE
11445 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
11446#endif
11447#ifdef _PC_REC_XFER_ALIGN
11448 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
11449#endif
11450#ifdef _PC_SYMLINK_MAX
11451 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
11452#endif
11453#ifdef _PC_XATTR_ENABLED
11454 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
11455#endif
11456#ifdef _PC_XATTR_EXISTS
11457 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
11458#endif
11459#ifdef _PC_TIMESTAMP_RESOLUTION
11460 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
11461#endif
Fred Drakec9680921999-12-13 16:37:25 +000011462};
11463
Fred Drakec9680921999-12-13 16:37:25 +000011464static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011465conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011466{
11467 return conv_confname(arg, valuep, posix_constants_pathconf,
11468 sizeof(posix_constants_pathconf)
11469 / sizeof(struct constdef));
11470}
11471#endif
11472
Larry Hastings2f936352014-08-05 14:04:04 +100011473
Fred Drakec9680921999-12-13 16:37:25 +000011474#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011475/*[clinic input]
11476os.fpathconf -> long
11477
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011478 fd: fildes
Larry Hastings2f936352014-08-05 14:04:04 +100011479 name: path_confname
11480 /
11481
11482Return the configuration limit name for the file descriptor fd.
11483
11484If there is no limit, return -1.
11485[clinic start generated code]*/
11486
Larry Hastings2f936352014-08-05 14:04:04 +100011487static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011488os_fpathconf_impl(PyObject *module, int fd, int name)
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011489/*[clinic end generated code: output=d5b7042425fc3e21 input=5b8d2471cfaae186]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011490{
11491 long limit;
11492
11493 errno = 0;
11494 limit = fpathconf(fd, name);
11495 if (limit == -1 && errno != 0)
11496 posix_error();
11497
11498 return limit;
11499}
11500#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011501
11502
11503#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011504/*[clinic input]
11505os.pathconf -> long
11506 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
11507 name: path_confname
11508
11509Return the configuration limit name for the file or directory path.
11510
11511If there is no limit, return -1.
11512On some platforms, path may also be specified as an open file descriptor.
11513 If this functionality is unavailable, using it raises an exception.
11514[clinic start generated code]*/
11515
Larry Hastings2f936352014-08-05 14:04:04 +100011516static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011517os_pathconf_impl(PyObject *module, path_t *path, int name)
11518/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011519{
Victor Stinner8c62be82010-05-06 00:08:46 +000011520 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000011521
Victor Stinner8c62be82010-05-06 00:08:46 +000011522 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020011523#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011524 if (path->fd != -1)
11525 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011526 else
11527#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011528 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011529 if (limit == -1 && errno != 0) {
11530 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011531 /* could be a path or name problem */
11532 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011533 else
Larry Hastings2f936352014-08-05 14:04:04 +100011534 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011535 }
Larry Hastings2f936352014-08-05 14:04:04 +100011536
11537 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011538}
Larry Hastings2f936352014-08-05 14:04:04 +100011539#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011540
11541#ifdef HAVE_CONFSTR
11542static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011543#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011544 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011545#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011546#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011547 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011548#endif
11549#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011550 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011551#endif
Fred Draked86ed291999-12-15 15:34:33 +000011552#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011553 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011554#endif
11555#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011556 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011557#endif
11558#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011559 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011560#endif
11561#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011562 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011563#endif
Fred Drakec9680921999-12-13 16:37:25 +000011564#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011565 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011566#endif
11567#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011568 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011569#endif
11570#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011571 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011572#endif
11573#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011574 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011575#endif
11576#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011577 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011578#endif
11579#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011580 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011581#endif
11582#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011583 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011584#endif
11585#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011586 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011587#endif
Fred Draked86ed291999-12-15 15:34:33 +000011588#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011589 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011590#endif
Fred Drakec9680921999-12-13 16:37:25 +000011591#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011592 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011593#endif
Fred Draked86ed291999-12-15 15:34:33 +000011594#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011595 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011596#endif
11597#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011598 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011599#endif
11600#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011601 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011602#endif
11603#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011604 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011605#endif
Fred Drakec9680921999-12-13 16:37:25 +000011606#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011607 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011608#endif
11609#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011610 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011611#endif
11612#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011613 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011614#endif
11615#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011616 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011617#endif
11618#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011619 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011620#endif
11621#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011622 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011623#endif
11624#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011625 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011626#endif
11627#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011628 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011629#endif
11630#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011631 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011632#endif
11633#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011634 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011635#endif
11636#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011637 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011638#endif
11639#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011640 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011641#endif
11642#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011643 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011644#endif
11645#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011646 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011647#endif
11648#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011649 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011650#endif
11651#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011652 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011653#endif
Fred Draked86ed291999-12-15 15:34:33 +000011654#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011655 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011656#endif
11657#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011658 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011659#endif
11660#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011661 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011662#endif
11663#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011664 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011665#endif
11666#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011667 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011668#endif
11669#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011670 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011671#endif
11672#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011673 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011674#endif
11675#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011676 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011677#endif
11678#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011679 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011680#endif
11681#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011682 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011683#endif
11684#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011685 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011686#endif
11687#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011688 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011689#endif
11690#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011691 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011692#endif
Fred Drakec9680921999-12-13 16:37:25 +000011693};
11694
11695static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011696conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011697{
11698 return conv_confname(arg, valuep, posix_constants_confstr,
11699 sizeof(posix_constants_confstr)
11700 / sizeof(struct constdef));
11701}
11702
Larry Hastings2f936352014-08-05 14:04:04 +100011703
11704/*[clinic input]
11705os.confstr
11706
11707 name: confstr_confname
11708 /
11709
11710Return a string-valued system configuration variable.
11711[clinic start generated code]*/
11712
Larry Hastings2f936352014-08-05 14:04:04 +100011713static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011714os_confstr_impl(PyObject *module, int name)
11715/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011716{
11717 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011718 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011719 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011720
Victor Stinnercb043522010-09-10 23:49:04 +000011721 errno = 0;
11722 len = confstr(name, buffer, sizeof(buffer));
11723 if (len == 0) {
11724 if (errno) {
11725 posix_error();
11726 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011727 }
11728 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011729 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011730 }
11731 }
Victor Stinnercb043522010-09-10 23:49:04 +000011732
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011733 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011734 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011735 char *buf = PyMem_Malloc(len);
11736 if (buf == NULL)
11737 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011738 len2 = confstr(name, buf, len);
11739 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011740 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011741 PyMem_Free(buf);
11742 }
11743 else
11744 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011745 return result;
11746}
Larry Hastings2f936352014-08-05 14:04:04 +100011747#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011748
11749
11750#ifdef HAVE_SYSCONF
11751static struct constdef posix_constants_sysconf[] = {
11752#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011753 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011754#endif
11755#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011756 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011757#endif
11758#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011759 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011760#endif
11761#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011762 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011763#endif
11764#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011765 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011766#endif
11767#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011768 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011769#endif
11770#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011771 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011772#endif
11773#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011774 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011775#endif
11776#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011777 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011778#endif
11779#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011780 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011781#endif
Fred Draked86ed291999-12-15 15:34:33 +000011782#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011783 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011784#endif
11785#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011786 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011787#endif
Fred Drakec9680921999-12-13 16:37:25 +000011788#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011789 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011790#endif
Fred Drakec9680921999-12-13 16:37:25 +000011791#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011792 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011793#endif
11794#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011795 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011796#endif
11797#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011798 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011799#endif
11800#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011801 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011802#endif
11803#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011804 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011805#endif
Fred Draked86ed291999-12-15 15:34:33 +000011806#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011807 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011808#endif
Fred Drakec9680921999-12-13 16:37:25 +000011809#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011810 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011811#endif
11812#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011813 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011814#endif
11815#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011816 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011817#endif
11818#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011819 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011820#endif
11821#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011822 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011823#endif
Fred Draked86ed291999-12-15 15:34:33 +000011824#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011825 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011826#endif
Fred Drakec9680921999-12-13 16:37:25 +000011827#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011828 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011829#endif
11830#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011831 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011832#endif
11833#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011834 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011835#endif
11836#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011837 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011838#endif
11839#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011840 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011841#endif
11842#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011843 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011844#endif
11845#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011846 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011847#endif
11848#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011849 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011850#endif
11851#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011852 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011853#endif
11854#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011855 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011856#endif
11857#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011858 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011859#endif
11860#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011861 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011862#endif
11863#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011864 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011865#endif
11866#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011867 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011868#endif
11869#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011870 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011871#endif
11872#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011873 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011874#endif
11875#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011876 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011877#endif
11878#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011879 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011880#endif
11881#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011882 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011883#endif
11884#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011885 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011886#endif
11887#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011888 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011889#endif
11890#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011891 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011892#endif
11893#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011894 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011895#endif
Fred Draked86ed291999-12-15 15:34:33 +000011896#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011897 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011898#endif
Fred Drakec9680921999-12-13 16:37:25 +000011899#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011900 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011901#endif
11902#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011903 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011904#endif
11905#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011906 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011907#endif
Fred Draked86ed291999-12-15 15:34:33 +000011908#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011909 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011910#endif
Fred Drakec9680921999-12-13 16:37:25 +000011911#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011912 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011913#endif
Fred Draked86ed291999-12-15 15:34:33 +000011914#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011915 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011916#endif
11917#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011918 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011919#endif
Fred Drakec9680921999-12-13 16:37:25 +000011920#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011921 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011922#endif
11923#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011924 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011925#endif
11926#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011927 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011928#endif
11929#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011930 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011931#endif
Fred Draked86ed291999-12-15 15:34:33 +000011932#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011933 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011934#endif
Fred Drakec9680921999-12-13 16:37:25 +000011935#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011936 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011937#endif
11938#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011939 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011940#endif
11941#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011942 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011943#endif
11944#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011945 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011946#endif
11947#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011948 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011949#endif
11950#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011951 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011952#endif
11953#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011954 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011955#endif
Fred Draked86ed291999-12-15 15:34:33 +000011956#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011957 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011958#endif
Fred Drakec9680921999-12-13 16:37:25 +000011959#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011960 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011961#endif
11962#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011963 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011964#endif
Fred Draked86ed291999-12-15 15:34:33 +000011965#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011966 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011967#endif
Fred Drakec9680921999-12-13 16:37:25 +000011968#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011969 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011970#endif
11971#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011972 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011973#endif
11974#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011975 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011976#endif
11977#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011978 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011979#endif
11980#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011981 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011982#endif
11983#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011984 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011985#endif
11986#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011987 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011988#endif
11989#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011990 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011991#endif
11992#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011993 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000011994#endif
Fred Draked86ed291999-12-15 15:34:33 +000011995#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011996 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000011997#endif
11998#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011999 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000012000#endif
Fred Drakec9680921999-12-13 16:37:25 +000012001#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000012002 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000012003#endif
12004#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012005 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012006#endif
12007#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012008 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012009#endif
12010#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012011 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012012#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030012013#ifdef _SC_AIX_REALMEM
12014 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
12015#endif
Fred Drakec9680921999-12-13 16:37:25 +000012016#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012017 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012018#endif
12019#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000012020 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000012021#endif
12022#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000012023 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000012024#endif
12025#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000012026 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000012027#endif
12028#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012029 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000012030#endif
12031#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012032 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000012033#endif
12034#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000012035 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000012036#endif
12037#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012038 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000012039#endif
12040#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012041 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000012042#endif
12043#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000012044 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000012045#endif
12046#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000012047 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000012048#endif
12049#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000012050 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000012051#endif
12052#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000012053 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000012054#endif
12055#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012056 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012057#endif
12058#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012059 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012060#endif
12061#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000012062 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000012063#endif
12064#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012065 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012066#endif
12067#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012068 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012069#endif
12070#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000012071 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000012072#endif
12073#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012074 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012075#endif
12076#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012077 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012078#endif
12079#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012080 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000012081#endif
12082#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000012083 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000012084#endif
12085#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012086 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012087#endif
12088#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012089 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012090#endif
12091#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012092 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000012093#endif
12094#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012095 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012096#endif
12097#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012098 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012099#endif
12100#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012101 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012102#endif
12103#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012104 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012105#endif
12106#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012107 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012108#endif
Fred Draked86ed291999-12-15 15:34:33 +000012109#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000012110 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000012111#endif
Fred Drakec9680921999-12-13 16:37:25 +000012112#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000012113 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000012114#endif
12115#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012116 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012117#endif
12118#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000012119 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000012120#endif
12121#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012122 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012123#endif
12124#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012125 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012126#endif
12127#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012128 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012129#endif
12130#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000012131 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000012132#endif
12133#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012134 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012135#endif
12136#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012137 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012138#endif
12139#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012140 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012141#endif
12142#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012143 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012144#endif
12145#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012146 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000012147#endif
12148#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012149 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000012150#endif
12151#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000012152 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000012153#endif
12154#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012155 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012156#endif
12157#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012158 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012159#endif
12160#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012161 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012162#endif
12163#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000012164 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000012165#endif
12166#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012167 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012168#endif
12169#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012170 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012171#endif
12172#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012173 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012174#endif
12175#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012176 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012177#endif
12178#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012179 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012180#endif
12181#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012182 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012183#endif
12184#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000012185 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000012186#endif
12187#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012188 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012189#endif
12190#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012191 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012192#endif
12193#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012194 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012195#endif
12196#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012197 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000012198#endif
12199#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000012200 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000012201#endif
12202#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012203 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012204#endif
12205#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000012206 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000012207#endif
12208#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012209 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012210#endif
12211#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000012212 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000012213#endif
12214#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000012215 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000012216#endif
12217#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000012218 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000012219#endif
12220#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012221 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000012222#endif
12223#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012224 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012225#endif
12226#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000012227 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000012228#endif
12229#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000012230 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000012231#endif
12232#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012233 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012234#endif
12235#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012236 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012237#endif
12238#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000012239 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000012240#endif
12241#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000012242 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000012243#endif
12244#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000012245 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000012246#endif
12247};
12248
12249static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012250conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000012251{
12252 return conv_confname(arg, valuep, posix_constants_sysconf,
12253 sizeof(posix_constants_sysconf)
12254 / sizeof(struct constdef));
12255}
12256
Larry Hastings2f936352014-08-05 14:04:04 +100012257
12258/*[clinic input]
12259os.sysconf -> long
12260 name: sysconf_confname
12261 /
12262
12263Return an integer-valued system configuration variable.
12264[clinic start generated code]*/
12265
Larry Hastings2f936352014-08-05 14:04:04 +100012266static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012267os_sysconf_impl(PyObject *module, int name)
12268/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012269{
12270 long value;
12271
12272 errno = 0;
12273 value = sysconf(name);
12274 if (value == -1 && errno != 0)
12275 posix_error();
12276 return value;
12277}
12278#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000012279
12280
Fred Drakebec628d1999-12-15 18:31:10 +000012281/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020012282 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000012283 * the exported dictionaries that are used to publish information about the
12284 * names available on the host platform.
12285 *
12286 * Sorting the table at runtime ensures that the table is properly ordered
12287 * when used, even for platforms we're not able to test on. It also makes
12288 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000012289 */
Fred Drakebec628d1999-12-15 18:31:10 +000012290
12291static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012292cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000012293{
12294 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012295 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000012296 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012297 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000012298
12299 return strcmp(c1->name, c2->name);
12300}
12301
12302static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012303setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012304 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012305{
Fred Drakebec628d1999-12-15 18:31:10 +000012306 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000012307 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000012308
12309 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
12310 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000012311 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000012312 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012313
Barry Warsaw3155db32000-04-13 15:20:40 +000012314 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000012315 PyObject *o = PyLong_FromLong(table[i].value);
12316 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
12317 Py_XDECREF(o);
12318 Py_DECREF(d);
12319 return -1;
12320 }
12321 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000012322 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000012323 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000012324}
12325
Fred Drakebec628d1999-12-15 18:31:10 +000012326/* Return -1 on failure, 0 on success. */
12327static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000012328setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012329{
12330#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000012331 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000012332 sizeof(posix_constants_pathconf)
12333 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012334 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012335 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012336#endif
12337#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000012338 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000012339 sizeof(posix_constants_confstr)
12340 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012341 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012342 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012343#endif
12344#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000012345 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000012346 sizeof(posix_constants_sysconf)
12347 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012348 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012349 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012350#endif
Fred Drakebec628d1999-12-15 18:31:10 +000012351 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000012352}
Fred Draked86ed291999-12-15 15:34:33 +000012353
12354
Larry Hastings2f936352014-08-05 14:04:04 +100012355/*[clinic input]
12356os.abort
12357
12358Abort the interpreter immediately.
12359
12360This function 'dumps core' or otherwise fails in the hardest way possible
12361on the hosting operating system. This function never returns.
12362[clinic start generated code]*/
12363
Larry Hastings2f936352014-08-05 14:04:04 +100012364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012365os_abort_impl(PyObject *module)
12366/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012367{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012368 abort();
12369 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010012370#ifndef __clang__
12371 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
12372 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
12373 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012374 Py_FatalError("abort() called from Python code didn't abort!");
12375 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010012376#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012377}
Fred Drakebec628d1999-12-15 18:31:10 +000012378
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000012379#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012380/* Grab ShellExecute dynamically from shell32 */
12381static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012382static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
12383 LPCWSTR, INT);
12384static int
12385check_ShellExecute()
12386{
12387 HINSTANCE hShell32;
12388
12389 /* only recheck */
12390 if (-1 == has_ShellExecute) {
12391 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070012392 /* Security note: this call is not vulnerable to "DLL hijacking".
12393 SHELL32 is part of "KnownDLLs" and so Windows always load
12394 the system SHELL32.DLL, even if there is another SHELL32.DLL
12395 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080012396 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080012397 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080012398 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
12399 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070012400 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012401 } else {
12402 has_ShellExecute = 0;
12403 }
Tony Roberts4860f012019-02-02 18:16:42 +010012404 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012405 }
12406 return has_ShellExecute;
12407}
12408
12409
Steve Dowercc16be82016-09-08 10:35:16 -070012410/*[clinic input]
12411os.startfile
12412 filepath: path_t
12413 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000012414
Steve Dowercc16be82016-09-08 10:35:16 -070012415Start a file with its associated application.
12416
12417When "operation" is not specified or "open", this acts like
12418double-clicking the file in Explorer, or giving the file name as an
12419argument to the DOS "start" command: the file is opened with whatever
12420application (if any) its extension is associated.
12421When another "operation" is given, it specifies what should be done with
12422the file. A typical operation is "print".
12423
12424startfile returns as soon as the associated application is launched.
12425There is no option to wait for the application to close, and no way
12426to retrieve the application's exit status.
12427
12428The filepath is relative to the current directory. If you want to use
12429an absolute path, make sure the first character is not a slash ("/");
12430the underlying Win32 ShellExecute function doesn't work if it is.
12431[clinic start generated code]*/
12432
12433static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020012434os_startfile_impl(PyObject *module, path_t *filepath,
12435 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030012436/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070012437{
12438 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012439
12440 if(!check_ShellExecute()) {
12441 /* If the OS doesn't have ShellExecute, return a
12442 NotImplementedError. */
12443 return PyErr_Format(PyExc_NotImplementedError,
12444 "startfile not available on this platform");
12445 }
12446
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012447 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080012448 return NULL;
12449 }
12450
Victor Stinner8c62be82010-05-06 00:08:46 +000012451 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070012452 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080012453 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000012454 Py_END_ALLOW_THREADS
12455
Victor Stinner8c62be82010-05-06 00:08:46 +000012456 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070012457 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020012458 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012459 }
Steve Dowercc16be82016-09-08 10:35:16 -070012460 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000012461}
Larry Hastings2f936352014-08-05 14:04:04 +100012462#endif /* MS_WINDOWS */
12463
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012464
Martin v. Löwis438b5342002-12-27 10:16:42 +000012465#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100012466/*[clinic input]
12467os.getloadavg
12468
12469Return average recent system load information.
12470
12471Return the number of processes in the system run queue averaged over
12472the last 1, 5, and 15 minutes as a tuple of three floats.
12473Raises OSError if the load average was unobtainable.
12474[clinic start generated code]*/
12475
Larry Hastings2f936352014-08-05 14:04:04 +100012476static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012477os_getloadavg_impl(PyObject *module)
12478/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000012479{
12480 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000012481 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000012482 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
12483 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000012484 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000012485 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000012486}
Larry Hastings2f936352014-08-05 14:04:04 +100012487#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000012488
Larry Hastings2f936352014-08-05 14:04:04 +100012489
12490/*[clinic input]
12491os.device_encoding
12492 fd: int
12493
12494Return a string describing the encoding of a terminal's file descriptor.
12495
12496The file descriptor must be attached to a terminal.
12497If the device is not a terminal, return None.
12498[clinic start generated code]*/
12499
Larry Hastings2f936352014-08-05 14:04:04 +100012500static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012501os_device_encoding_impl(PyObject *module, int fd)
12502/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012503{
Brett Cannonefb00c02012-02-29 18:31:31 -050012504 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000012505}
12506
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012507
Larry Hastings2f936352014-08-05 14:04:04 +100012508#ifdef HAVE_SETRESUID
12509/*[clinic input]
12510os.setresuid
12511
12512 ruid: uid_t
12513 euid: uid_t
12514 suid: uid_t
12515 /
12516
12517Set the current process's real, effective, and saved user ids.
12518[clinic start generated code]*/
12519
Larry Hastings2f936352014-08-05 14:04:04 +100012520static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012521os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12522/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012523{
Victor Stinner8c62be82010-05-06 00:08:46 +000012524 if (setresuid(ruid, euid, suid) < 0)
12525 return posix_error();
12526 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012527}
Larry Hastings2f936352014-08-05 14:04:04 +100012528#endif /* HAVE_SETRESUID */
12529
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012530
12531#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012532/*[clinic input]
12533os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012534
Larry Hastings2f936352014-08-05 14:04:04 +100012535 rgid: gid_t
12536 egid: gid_t
12537 sgid: gid_t
12538 /
12539
12540Set the current process's real, effective, and saved group ids.
12541[clinic start generated code]*/
12542
Larry Hastings2f936352014-08-05 14:04:04 +100012543static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012544os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12545/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012546{
Victor Stinner8c62be82010-05-06 00:08:46 +000012547 if (setresgid(rgid, egid, sgid) < 0)
12548 return posix_error();
12549 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012550}
Larry Hastings2f936352014-08-05 14:04:04 +100012551#endif /* HAVE_SETRESGID */
12552
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012553
12554#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012555/*[clinic input]
12556os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012557
Larry Hastings2f936352014-08-05 14:04:04 +100012558Return a tuple of the current process's real, effective, and saved user ids.
12559[clinic start generated code]*/
12560
Larry Hastings2f936352014-08-05 14:04:04 +100012561static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012562os_getresuid_impl(PyObject *module)
12563/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012564{
Victor Stinner8c62be82010-05-06 00:08:46 +000012565 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012566 if (getresuid(&ruid, &euid, &suid) < 0)
12567 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012568 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12569 _PyLong_FromUid(euid),
12570 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012571}
Larry Hastings2f936352014-08-05 14:04:04 +100012572#endif /* HAVE_GETRESUID */
12573
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012574
12575#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012576/*[clinic input]
12577os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012578
Larry Hastings2f936352014-08-05 14:04:04 +100012579Return a tuple of the current process's real, effective, and saved group ids.
12580[clinic start generated code]*/
12581
Larry Hastings2f936352014-08-05 14:04:04 +100012582static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012583os_getresgid_impl(PyObject *module)
12584/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012585{
12586 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012587 if (getresgid(&rgid, &egid, &sgid) < 0)
12588 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012589 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12590 _PyLong_FromGid(egid),
12591 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012592}
Larry Hastings2f936352014-08-05 14:04:04 +100012593#endif /* HAVE_GETRESGID */
12594
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012595
Benjamin Peterson9428d532011-09-14 11:45:52 -040012596#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012597/*[clinic input]
12598os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012599
Larry Hastings2f936352014-08-05 14:04:04 +100012600 path: path_t(allow_fd=True)
12601 attribute: path_t
12602 *
12603 follow_symlinks: bool = True
12604
12605Return the value of extended attribute attribute on path.
12606
BNMetricsb9427072018-11-02 15:20:19 +000012607path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012608If follow_symlinks is False, and the last element of the path is a symbolic
12609 link, getxattr will examine the symbolic link itself instead of the file
12610 the link points to.
12611
12612[clinic start generated code]*/
12613
Larry Hastings2f936352014-08-05 14:04:04 +100012614static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012615os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012616 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012617/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012618{
12619 Py_ssize_t i;
12620 PyObject *buffer = NULL;
12621
12622 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12623 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012624
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012625 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12626 return NULL;
12627 }
12628
Larry Hastings9cf065c2012-06-22 16:30:09 -070012629 for (i = 0; ; i++) {
12630 void *ptr;
12631 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012632 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012633 Py_ssize_t buffer_size = buffer_sizes[i];
12634 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012635 path_error(path);
12636 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012637 }
12638 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12639 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012640 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012641 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012642
Larry Hastings9cf065c2012-06-22 16:30:09 -070012643 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012644 if (path->fd >= 0)
12645 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012646 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012647 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012648 else
Larry Hastings2f936352014-08-05 14:04:04 +100012649 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012650 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012651
Larry Hastings9cf065c2012-06-22 16:30:09 -070012652 if (result < 0) {
12653 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012654 if (errno == ERANGE)
12655 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012656 path_error(path);
12657 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012658 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012659
Larry Hastings9cf065c2012-06-22 16:30:09 -070012660 if (result != buffer_size) {
12661 /* Can only shrink. */
12662 _PyBytes_Resize(&buffer, result);
12663 }
12664 break;
12665 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012666
Larry Hastings9cf065c2012-06-22 16:30:09 -070012667 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012668}
12669
Larry Hastings2f936352014-08-05 14:04:04 +100012670
12671/*[clinic input]
12672os.setxattr
12673
12674 path: path_t(allow_fd=True)
12675 attribute: path_t
12676 value: Py_buffer
12677 flags: int = 0
12678 *
12679 follow_symlinks: bool = True
12680
12681Set extended attribute attribute on path to value.
12682
BNMetricsb9427072018-11-02 15:20:19 +000012683path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012684If follow_symlinks is False, and the last element of the path is a symbolic
12685 link, setxattr will modify the symbolic link itself instead of the file
12686 the link points to.
12687
12688[clinic start generated code]*/
12689
Benjamin Peterson799bd802011-08-31 22:15:17 -040012690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012691os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012692 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012693/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012694{
Larry Hastings2f936352014-08-05 14:04:04 +100012695 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012696
Larry Hastings2f936352014-08-05 14:04:04 +100012697 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012698 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012699
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012700 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12701 value->buf, value->len, flags) < 0) {
12702 return NULL;
12703 }
12704
Benjamin Peterson799bd802011-08-31 22:15:17 -040012705 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012706 if (path->fd > -1)
12707 result = fsetxattr(path->fd, attribute->narrow,
12708 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012709 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012710 result = setxattr(path->narrow, attribute->narrow,
12711 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012712 else
Larry Hastings2f936352014-08-05 14:04:04 +100012713 result = lsetxattr(path->narrow, attribute->narrow,
12714 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012715 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012716
Larry Hastings9cf065c2012-06-22 16:30:09 -070012717 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012718 path_error(path);
12719 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012720 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012721
Larry Hastings2f936352014-08-05 14:04:04 +100012722 Py_RETURN_NONE;
12723}
12724
12725
12726/*[clinic input]
12727os.removexattr
12728
12729 path: path_t(allow_fd=True)
12730 attribute: path_t
12731 *
12732 follow_symlinks: bool = True
12733
12734Remove extended attribute attribute on path.
12735
BNMetricsb9427072018-11-02 15:20:19 +000012736path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012737If follow_symlinks is False, and the last element of the path is a symbolic
12738 link, removexattr will modify the symbolic link itself instead of the file
12739 the link points to.
12740
12741[clinic start generated code]*/
12742
Larry Hastings2f936352014-08-05 14:04:04 +100012743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012744os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012745 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012746/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012747{
12748 ssize_t result;
12749
12750 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12751 return NULL;
12752
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012753 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12754 return NULL;
12755 }
12756
Larry Hastings2f936352014-08-05 14:04:04 +100012757 Py_BEGIN_ALLOW_THREADS;
12758 if (path->fd > -1)
12759 result = fremovexattr(path->fd, attribute->narrow);
12760 else if (follow_symlinks)
12761 result = removexattr(path->narrow, attribute->narrow);
12762 else
12763 result = lremovexattr(path->narrow, attribute->narrow);
12764 Py_END_ALLOW_THREADS;
12765
12766 if (result) {
12767 return path_error(path);
12768 }
12769
12770 Py_RETURN_NONE;
12771}
12772
12773
12774/*[clinic input]
12775os.listxattr
12776
12777 path: path_t(allow_fd=True, nullable=True) = None
12778 *
12779 follow_symlinks: bool = True
12780
12781Return a list of extended attributes on path.
12782
BNMetricsb9427072018-11-02 15:20:19 +000012783path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012784if path is None, listxattr will examine the current directory.
12785If follow_symlinks is False, and the last element of the path is a symbolic
12786 link, listxattr will examine the symbolic link itself instead of the file
12787 the link points to.
12788[clinic start generated code]*/
12789
Larry Hastings2f936352014-08-05 14:04:04 +100012790static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012791os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012792/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012793{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012794 Py_ssize_t i;
12795 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012796 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012797 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012798
Larry Hastings2f936352014-08-05 14:04:04 +100012799 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012800 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012801
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012802 if (PySys_Audit("os.listxattr", "(O)",
12803 path->object ? path->object : Py_None) < 0) {
12804 return NULL;
12805 }
12806
Larry Hastings2f936352014-08-05 14:04:04 +100012807 name = path->narrow ? path->narrow : ".";
12808
Larry Hastings9cf065c2012-06-22 16:30:09 -070012809 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012810 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012811 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012812 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012813 Py_ssize_t buffer_size = buffer_sizes[i];
12814 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012815 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012816 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012817 break;
12818 }
Victor Stinner00d7abd2020-12-01 09:56:42 +010012819 buffer = PyMem_Malloc(buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012820 if (!buffer) {
12821 PyErr_NoMemory();
12822 break;
12823 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012824
Larry Hastings9cf065c2012-06-22 16:30:09 -070012825 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012826 if (path->fd > -1)
12827 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012828 else if (follow_symlinks)
12829 length = listxattr(name, buffer, buffer_size);
12830 else
12831 length = llistxattr(name, buffer, buffer_size);
12832 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012833
Larry Hastings9cf065c2012-06-22 16:30:09 -070012834 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012835 if (errno == ERANGE) {
Victor Stinner00d7abd2020-12-01 09:56:42 +010012836 PyMem_Free(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012837 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012838 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012839 }
Larry Hastings2f936352014-08-05 14:04:04 +100012840 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012841 break;
12842 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012843
Larry Hastings9cf065c2012-06-22 16:30:09 -070012844 result = PyList_New(0);
12845 if (!result) {
12846 goto exit;
12847 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012848
Larry Hastings9cf065c2012-06-22 16:30:09 -070012849 end = buffer + length;
12850 for (trace = start = buffer; trace != end; trace++) {
12851 if (!*trace) {
12852 int error;
12853 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12854 trace - start);
12855 if (!attribute) {
12856 Py_DECREF(result);
12857 result = NULL;
12858 goto exit;
12859 }
12860 error = PyList_Append(result, attribute);
12861 Py_DECREF(attribute);
12862 if (error) {
12863 Py_DECREF(result);
12864 result = NULL;
12865 goto exit;
12866 }
12867 start = trace + 1;
12868 }
12869 }
12870 break;
12871 }
12872exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012873 if (buffer)
Victor Stinner00d7abd2020-12-01 09:56:42 +010012874 PyMem_Free(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012875 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012876}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012877#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012878
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012879
Larry Hastings2f936352014-08-05 14:04:04 +100012880/*[clinic input]
12881os.urandom
12882
12883 size: Py_ssize_t
12884 /
12885
12886Return a bytes object containing random bytes suitable for cryptographic use.
12887[clinic start generated code]*/
12888
Larry Hastings2f936352014-08-05 14:04:04 +100012889static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012890os_urandom_impl(PyObject *module, Py_ssize_t size)
12891/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012892{
12893 PyObject *bytes;
12894 int result;
12895
Georg Brandl2fb477c2012-02-21 00:33:36 +010012896 if (size < 0)
12897 return PyErr_Format(PyExc_ValueError,
12898 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012899 bytes = PyBytes_FromStringAndSize(NULL, size);
12900 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012901 return NULL;
12902
Victor Stinnere66987e2016-09-06 16:33:52 -070012903 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012904 if (result == -1) {
12905 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012906 return NULL;
12907 }
Larry Hastings2f936352014-08-05 14:04:04 +100012908 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012909}
12910
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012911#ifdef HAVE_MEMFD_CREATE
12912/*[clinic input]
12913os.memfd_create
12914
12915 name: FSConverter
12916 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12917
12918[clinic start generated code]*/
12919
12920static PyObject *
12921os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12922/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12923{
12924 int fd;
12925 const char *bytes = PyBytes_AS_STRING(name);
12926 Py_BEGIN_ALLOW_THREADS
12927 fd = memfd_create(bytes, flags);
12928 Py_END_ALLOW_THREADS
12929 if (fd == -1) {
12930 return PyErr_SetFromErrno(PyExc_OSError);
12931 }
12932 return PyLong_FromLong(fd);
12933}
12934#endif
12935
Christian Heimescd9fed62020-11-13 19:48:52 +010012936#ifdef HAVE_EVENTFD
12937/*[clinic input]
12938os.eventfd
12939
12940 initval: unsigned_int
12941 flags: int(c_default="EFD_CLOEXEC") = EFD_CLOEXEC
12942
12943Creates and returns an event notification file descriptor.
12944[clinic start generated code]*/
12945
12946static PyObject *
12947os_eventfd_impl(PyObject *module, unsigned int initval, int flags)
12948/*[clinic end generated code: output=ce9c9bbd1446f2de input=66203e3c50c4028b]*/
12949
12950{
12951 /* initval is limited to uint32_t, internal counter is uint64_t */
12952 int fd;
12953 Py_BEGIN_ALLOW_THREADS
12954 fd = eventfd(initval, flags);
12955 Py_END_ALLOW_THREADS
12956 if (fd == -1) {
12957 return PyErr_SetFromErrno(PyExc_OSError);
12958 }
12959 return PyLong_FromLong(fd);
12960}
12961
12962/*[clinic input]
12963os.eventfd_read
12964
12965 fd: fildes
12966
12967Read eventfd value
12968[clinic start generated code]*/
12969
12970static PyObject *
12971os_eventfd_read_impl(PyObject *module, int fd)
12972/*[clinic end generated code: output=8f2c7b59a3521fd1 input=110f8b57fa596afe]*/
12973{
12974 eventfd_t value;
12975 int result;
12976 Py_BEGIN_ALLOW_THREADS
12977 result = eventfd_read(fd, &value);
12978 Py_END_ALLOW_THREADS
12979 if (result == -1) {
12980 return PyErr_SetFromErrno(PyExc_OSError);
12981 }
12982 return PyLong_FromUnsignedLongLong(value);
12983}
12984
12985/*[clinic input]
12986os.eventfd_write
12987
12988 fd: fildes
12989 value: unsigned_long_long
12990
12991Write eventfd value.
12992[clinic start generated code]*/
12993
12994static PyObject *
12995os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value)
12996/*[clinic end generated code: output=bebd9040bbf987f5 input=156de8555be5a949]*/
12997{
12998 int result;
12999 Py_BEGIN_ALLOW_THREADS
13000 result = eventfd_write(fd, value);
13001 Py_END_ALLOW_THREADS
13002 if (result == -1) {
13003 return PyErr_SetFromErrno(PyExc_OSError);
13004 }
13005 Py_RETURN_NONE;
13006}
13007#endif /* HAVE_EVENTFD */
13008
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013009/* Terminal size querying */
13010
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013011PyDoc_STRVAR(TerminalSize_docstring,
13012 "A tuple of (columns, lines) for holding terminal window size");
13013
13014static PyStructSequence_Field TerminalSize_fields[] = {
13015 {"columns", "width of the terminal window in characters"},
13016 {"lines", "height of the terminal window in characters"},
13017 {NULL, NULL}
13018};
13019
13020static PyStructSequence_Desc TerminalSize_desc = {
13021 "os.terminal_size",
13022 TerminalSize_docstring,
13023 TerminalSize_fields,
13024 2,
13025};
13026
13027#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013028/*[clinic input]
13029os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013030
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013031 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
13032 /
13033
13034Return the size of the terminal window as (columns, lines).
13035
13036The optional argument fd (default standard output) specifies
13037which file descriptor should be queried.
13038
13039If the file descriptor is not connected to a terminal, an OSError
13040is thrown.
13041
13042This function will only be defined if an implementation is
13043available for this system.
13044
13045shutil.get_terminal_size is the high-level function which should
13046normally be used, os.get_terminal_size is the low-level implementation.
13047[clinic start generated code]*/
13048
13049static PyObject *
13050os_get_terminal_size_impl(PyObject *module, int fd)
13051/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013052{
13053 int columns, lines;
13054 PyObject *termsize;
13055
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013056 /* Under some conditions stdout may not be connected and
13057 * fileno(stdout) may point to an invalid file descriptor. For example
13058 * GUI apps don't have valid standard streams by default.
13059 *
13060 * If this happens, and the optional fd argument is not present,
13061 * the ioctl below will fail returning EBADF. This is what we want.
13062 */
13063
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013064#ifdef TERMSIZE_USE_IOCTL
13065 {
13066 struct winsize w;
13067 if (ioctl(fd, TIOCGWINSZ, &w))
13068 return PyErr_SetFromErrno(PyExc_OSError);
13069 columns = w.ws_col;
13070 lines = w.ws_row;
13071 }
13072#endif /* TERMSIZE_USE_IOCTL */
13073
13074#ifdef TERMSIZE_USE_CONIO
13075 {
13076 DWORD nhandle;
13077 HANDLE handle;
13078 CONSOLE_SCREEN_BUFFER_INFO csbi;
13079 switch (fd) {
13080 case 0: nhandle = STD_INPUT_HANDLE;
13081 break;
13082 case 1: nhandle = STD_OUTPUT_HANDLE;
13083 break;
13084 case 2: nhandle = STD_ERROR_HANDLE;
13085 break;
13086 default:
13087 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
13088 }
13089 handle = GetStdHandle(nhandle);
13090 if (handle == NULL)
13091 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
13092 if (handle == INVALID_HANDLE_VALUE)
13093 return PyErr_SetFromWindowsErr(0);
13094
13095 if (!GetConsoleScreenBufferInfo(handle, &csbi))
13096 return PyErr_SetFromWindowsErr(0);
13097
13098 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
13099 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
13100 }
13101#endif /* TERMSIZE_USE_CONIO */
13102
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013103 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013104 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013105 if (termsize == NULL)
13106 return NULL;
13107 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
13108 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
13109 if (PyErr_Occurred()) {
13110 Py_DECREF(termsize);
13111 return NULL;
13112 }
13113 return termsize;
13114}
13115#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
13116
Larry Hastings2f936352014-08-05 14:04:04 +100013117
13118/*[clinic input]
13119os.cpu_count
13120
Charles-François Natali80d62e62015-08-13 20:37:08 +010013121Return the number of CPUs in the system; return None if indeterminable.
13122
13123This number is not equivalent to the number of CPUs the current process can
13124use. The number of usable CPUs can be obtained with
13125``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100013126[clinic start generated code]*/
13127
Larry Hastings2f936352014-08-05 14:04:04 +100013128static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013129os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013130/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013131{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013132 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013133#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010013134 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013135#elif defined(__hpux)
13136 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
13137#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
13138 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
pxinwr3405e052020-08-07 13:21:52 +080013139#elif defined(__VXWORKS__)
13140 ncpu = _Py_popcount32(vxCpuEnabledGet());
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013141#elif defined(__DragonFly__) || \
13142 defined(__OpenBSD__) || \
13143 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013144 defined(__NetBSD__) || \
13145 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020013146 int mib[2];
13147 size_t len = sizeof(ncpu);
13148 mib[0] = CTL_HW;
13149 mib[1] = HW_NCPU;
13150 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
13151 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013152#endif
13153 if (ncpu >= 1)
13154 return PyLong_FromLong(ncpu);
13155 else
13156 Py_RETURN_NONE;
13157}
13158
Victor Stinnerdaf45552013-08-28 00:53:59 +020013159
Larry Hastings2f936352014-08-05 14:04:04 +100013160/*[clinic input]
13161os.get_inheritable -> bool
13162
13163 fd: int
13164 /
13165
13166Get the close-on-exe flag of the specified file descriptor.
13167[clinic start generated code]*/
13168
Larry Hastings2f936352014-08-05 14:04:04 +100013169static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013170os_get_inheritable_impl(PyObject *module, int fd)
13171/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013172{
Steve Dower8fc89802015-04-12 00:26:27 -040013173 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040013174 _Py_BEGIN_SUPPRESS_IPH
13175 return_value = _Py_get_inheritable(fd);
13176 _Py_END_SUPPRESS_IPH
13177 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100013178}
13179
13180
13181/*[clinic input]
13182os.set_inheritable
13183 fd: int
13184 inheritable: int
13185 /
13186
13187Set the inheritable flag of the specified file descriptor.
13188[clinic start generated code]*/
13189
Larry Hastings2f936352014-08-05 14:04:04 +100013190static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013191os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
13192/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020013193{
Steve Dower8fc89802015-04-12 00:26:27 -040013194 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013195
Steve Dower8fc89802015-04-12 00:26:27 -040013196 _Py_BEGIN_SUPPRESS_IPH
13197 result = _Py_set_inheritable(fd, inheritable, NULL);
13198 _Py_END_SUPPRESS_IPH
13199 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020013200 return NULL;
13201 Py_RETURN_NONE;
13202}
13203
13204
13205#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100013206/*[clinic input]
13207os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070013208 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013209 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020013210
Larry Hastings2f936352014-08-05 14:04:04 +100013211Get the close-on-exe flag of the specified file descriptor.
13212[clinic start generated code]*/
13213
Larry Hastings2f936352014-08-05 14:04:04 +100013214static int
Benjamin Petersonca470632016-09-06 13:47:26 -070013215os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070013216/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013217{
13218 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013219
13220 if (!GetHandleInformation((HANDLE)handle, &flags)) {
13221 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100013222 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013223 }
13224
Larry Hastings2f936352014-08-05 14:04:04 +100013225 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013226}
13227
Victor Stinnerdaf45552013-08-28 00:53:59 +020013228
Larry Hastings2f936352014-08-05 14:04:04 +100013229/*[clinic input]
13230os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070013231 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013232 inheritable: bool
13233 /
13234
13235Set the inheritable flag of the specified handle.
13236[clinic start generated code]*/
13237
Larry Hastings2f936352014-08-05 14:04:04 +100013238static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070013239os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040013240 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070013241/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013242{
13243 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013244 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
13245 PyErr_SetFromWindowsErr(0);
13246 return NULL;
13247 }
13248 Py_RETURN_NONE;
13249}
Larry Hastings2f936352014-08-05 14:04:04 +100013250#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013251
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013252#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013253/*[clinic input]
13254os.get_blocking -> bool
13255 fd: int
13256 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013257
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013258Get the blocking mode of the file descriptor.
13259
13260Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
13261[clinic start generated code]*/
13262
13263static int
13264os_get_blocking_impl(PyObject *module, int fd)
13265/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013266{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013267 int blocking;
13268
Steve Dower8fc89802015-04-12 00:26:27 -040013269 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013270 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040013271 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013272 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013273}
13274
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013275/*[clinic input]
13276os.set_blocking
13277 fd: int
13278 blocking: bool(accept={int})
13279 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013280
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013281Set the blocking mode of the specified file descriptor.
13282
13283Set the O_NONBLOCK flag if blocking is False,
13284clear the O_NONBLOCK flag otherwise.
13285[clinic start generated code]*/
13286
13287static PyObject *
13288os_set_blocking_impl(PyObject *module, int fd, int blocking)
13289/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013290{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013291 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013292
Steve Dower8fc89802015-04-12 00:26:27 -040013293 _Py_BEGIN_SUPPRESS_IPH
13294 result = _Py_set_blocking(fd, blocking);
13295 _Py_END_SUPPRESS_IPH
13296 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013297 return NULL;
13298 Py_RETURN_NONE;
13299}
13300#endif /* !MS_WINDOWS */
13301
13302
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013303/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080013304class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013305[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080013306/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013307
13308typedef struct {
13309 PyObject_HEAD
13310 PyObject *name;
13311 PyObject *path;
13312 PyObject *stat;
13313 PyObject *lstat;
13314#ifdef MS_WINDOWS
13315 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010013316 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010013317 int got_file_index;
13318#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010013319#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013320 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013321#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013322 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013323 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010013324#endif
13325} DirEntry;
13326
Eddie Elizondob3966632019-11-05 07:16:14 -080013327static PyObject *
13328_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
13329{
13330 PyErr_Format(PyExc_TypeError,
13331 "cannot create '%.100s' instances", _PyType_Name(type));
13332 return NULL;
13333}
13334
Victor Stinner6036e442015-03-08 01:58:04 +010013335static void
13336DirEntry_dealloc(DirEntry *entry)
13337{
Eddie Elizondob3966632019-11-05 07:16:14 -080013338 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010013339 Py_XDECREF(entry->name);
13340 Py_XDECREF(entry->path);
13341 Py_XDECREF(entry->stat);
13342 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080013343 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13344 free_func(entry);
13345 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013346}
13347
13348/* Forward reference */
13349static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013350DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13351 int follow_symlinks, unsigned short mode_bits);
Victor Stinner6036e442015-03-08 01:58:04 +010013352
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013353/*[clinic input]
13354os.DirEntry.is_symlink -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013355 defining_class: defining_class
13356 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013357
13358Return True if the entry is a symbolic link; cached per entry.
13359[clinic start generated code]*/
13360
Victor Stinner6036e442015-03-08 01:58:04 +010013361static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013362os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
13363/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013364{
13365#ifdef MS_WINDOWS
13366 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010013367#elif defined(HAVE_DIRENT_D_TYPE)
13368 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013369 if (self->d_type != DT_UNKNOWN)
13370 return self->d_type == DT_LNK;
13371 else
Victor Stinner97f33c32020-05-14 18:05:58 +020013372 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010013373#else
13374 /* POSIX without d_type */
Victor Stinner97f33c32020-05-14 18:05:58 +020013375 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010013376#endif
13377}
13378
13379static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013380DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
Victor Stinner6036e442015-03-08 01:58:04 +010013381{
13382 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013383 STRUCT_STAT st;
13384 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010013385
13386#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013387 if (!PyUnicode_FSDecoder(self->path, &ub))
13388 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013389#if USE_UNICODE_WCHAR_CACHE
13390_Py_COMP_DIAG_PUSH
13391_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013392 const wchar_t *path = PyUnicode_AsUnicode(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013393_Py_COMP_DIAG_POP
13394#else /* USE_UNICODE_WCHAR_CACHE */
13395 wchar_t *path = PyUnicode_AsWideCharString(ub, NULL);
13396 Py_DECREF(ub);
13397#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013398#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013399 if (!PyUnicode_FSConverter(self->path, &ub))
13400 return NULL;
13401 const char *path = PyBytes_AS_STRING(ub);
13402 if (self->dir_fd != DEFAULT_DIR_FD) {
13403#ifdef HAVE_FSTATAT
Ronald Oussoren41761932020-11-08 10:05:27 +010013404 if (HAVE_FSTATAT_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013405 result = fstatat(self->dir_fd, path, &st,
13406 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +010013407 } else
13408
13409#endif /* HAVE_FSTATAT */
13410 {
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013411 Py_DECREF(ub);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013412 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
13413 return NULL;
Ronald Oussoren41761932020-11-08 10:05:27 +010013414 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013415 }
13416 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013417#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013418 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013419 if (follow_symlinks)
13420 result = STAT(path, &st);
13421 else
13422 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013423 }
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013424#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE
13425 PyMem_Free(path);
13426#else /* USE_UNICODE_WCHAR_CACHE */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013427 Py_DECREF(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013428#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013429
13430 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013431 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013432
Victor Stinner97f33c32020-05-14 18:05:58 +020013433 return _pystat_fromstructstat(module, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010013434}
13435
13436static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013437DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
Victor Stinner6036e442015-03-08 01:58:04 +010013438{
13439 if (!self->lstat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013440 PyObject *module = PyType_GetModule(defining_class);
Victor Stinner6036e442015-03-08 01:58:04 +010013441#ifdef MS_WINDOWS
Victor Stinner97f33c32020-05-14 18:05:58 +020013442 self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010013443#else /* POSIX */
Victor Stinner97f33c32020-05-14 18:05:58 +020013444 self->lstat = DirEntry_fetch_stat(module, self, 0);
Victor Stinner6036e442015-03-08 01:58:04 +010013445#endif
13446 }
13447 Py_XINCREF(self->lstat);
13448 return self->lstat;
13449}
13450
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013451/*[clinic input]
13452os.DirEntry.stat
Victor Stinner97f33c32020-05-14 18:05:58 +020013453 defining_class: defining_class
13454 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013455 *
13456 follow_symlinks: bool = True
13457
13458Return stat_result object for the entry; cached per entry.
13459[clinic start generated code]*/
13460
Victor Stinner6036e442015-03-08 01:58:04 +010013461static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013462os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
13463 int follow_symlinks)
13464/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013465{
Victor Stinner97f33c32020-05-14 18:05:58 +020013466 if (!follow_symlinks) {
13467 return DirEntry_get_lstat(defining_class, self);
13468 }
Victor Stinner6036e442015-03-08 01:58:04 +010013469
13470 if (!self->stat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013471 int result = os_DirEntry_is_symlink_impl(self, defining_class);
13472 if (result == -1) {
Victor Stinner6036e442015-03-08 01:58:04 +010013473 return NULL;
Victor Stinner97f33c32020-05-14 18:05:58 +020013474 }
13475 if (result) {
13476 PyObject *module = PyType_GetModule(defining_class);
13477 self->stat = DirEntry_fetch_stat(module, self, 1);
13478 }
13479 else {
13480 self->stat = DirEntry_get_lstat(defining_class, self);
13481 }
Victor Stinner6036e442015-03-08 01:58:04 +010013482 }
13483
13484 Py_XINCREF(self->stat);
13485 return self->stat;
13486}
13487
Victor Stinner6036e442015-03-08 01:58:04 +010013488/* Set exception and return -1 on error, 0 for False, 1 for True */
13489static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013490DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13491 int follow_symlinks, unsigned short mode_bits)
Victor Stinner6036e442015-03-08 01:58:04 +010013492{
13493 PyObject *stat = NULL;
13494 PyObject *st_mode = NULL;
13495 long mode;
13496 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010013497#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013498 int is_symlink;
13499 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010013500#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013501#ifdef MS_WINDOWS
13502 unsigned long dir_bits;
13503#endif
13504
13505#ifdef MS_WINDOWS
13506 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
13507 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010013508#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013509 is_symlink = self->d_type == DT_LNK;
13510 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
13511#endif
13512
Victor Stinner35a97c02015-03-08 02:59:09 +010013513#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013514 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010013515#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020013516 stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010013517 if (!stat) {
13518 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
13519 /* If file doesn't exist (anymore), then return False
13520 (i.e., say it's not a file/directory) */
13521 PyErr_Clear();
13522 return 0;
13523 }
13524 goto error;
13525 }
Victor Stinner97f33c32020-05-14 18:05:58 +020013526 _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
13527 st_mode = PyObject_GetAttr(stat, state->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010013528 if (!st_mode)
13529 goto error;
13530
13531 mode = PyLong_AsLong(st_mode);
13532 if (mode == -1 && PyErr_Occurred())
13533 goto error;
13534 Py_CLEAR(st_mode);
13535 Py_CLEAR(stat);
13536 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010013537#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013538 }
13539 else if (is_symlink) {
13540 assert(mode_bits != S_IFLNK);
13541 result = 0;
13542 }
13543 else {
13544 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
13545#ifdef MS_WINDOWS
13546 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
13547 if (mode_bits == S_IFDIR)
13548 result = dir_bits != 0;
13549 else
13550 result = dir_bits == 0;
13551#else /* POSIX */
13552 if (mode_bits == S_IFDIR)
13553 result = self->d_type == DT_DIR;
13554 else
13555 result = self->d_type == DT_REG;
13556#endif
13557 }
Victor Stinner35a97c02015-03-08 02:59:09 +010013558#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013559
13560 return result;
13561
13562error:
13563 Py_XDECREF(st_mode);
13564 Py_XDECREF(stat);
13565 return -1;
13566}
13567
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013568/*[clinic input]
13569os.DirEntry.is_dir -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013570 defining_class: defining_class
13571 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013572 *
13573 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010013574
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013575Return True if the entry is a directory; cached per entry.
13576[clinic start generated code]*/
13577
13578static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013579os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
13580 int follow_symlinks)
13581/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013582{
Victor Stinner97f33c32020-05-14 18:05:58 +020013583 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010013584}
13585
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013586/*[clinic input]
13587os.DirEntry.is_file -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013588 defining_class: defining_class
13589 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013590 *
13591 follow_symlinks: bool = True
13592
13593Return True if the entry is a file; cached per entry.
13594[clinic start generated code]*/
13595
13596static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013597os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
13598 int follow_symlinks)
13599/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013600{
Victor Stinner97f33c32020-05-14 18:05:58 +020013601 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010013602}
13603
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013604/*[clinic input]
13605os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010013606
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013607Return inode of the entry; cached per entry.
13608[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013609
13610static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013611os_DirEntry_inode_impl(DirEntry *self)
13612/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013613{
13614#ifdef MS_WINDOWS
13615 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013616 PyObject *unicode;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013617 STRUCT_STAT stat;
13618 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010013619
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013620 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010013621 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013622#if USE_UNICODE_WCHAR_CACHE
13623_Py_COMP_DIAG_PUSH
13624_Py_COMP_DIAG_IGNORE_DEPR_DECLS
13625 const wchar_t *path = PyUnicode_AsUnicode(unicode);
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013626 result = LSTAT(path, &stat);
13627 Py_DECREF(unicode);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013628_Py_COMP_DIAG_POP
13629#else /* USE_UNICODE_WCHAR_CACHE */
13630 wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL);
13631 Py_DECREF(unicode);
13632 result = LSTAT(path, &stat);
13633 PyMem_Free(path);
13634#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013635
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013636 if (result != 0)
13637 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013638
13639 self->win32_file_index = stat.st_ino;
13640 self->got_file_index = 1;
13641 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013642 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13643 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013644#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013645 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13646 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013647#endif
13648}
13649
13650static PyObject *
13651DirEntry_repr(DirEntry *self)
13652{
13653 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13654}
13655
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013656/*[clinic input]
13657os.DirEntry.__fspath__
13658
13659Returns the path for the entry.
13660[clinic start generated code]*/
13661
Brett Cannon96881cd2016-06-10 14:37:21 -070013662static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013663os_DirEntry___fspath___impl(DirEntry *self)
13664/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013665{
13666 Py_INCREF(self->path);
13667 return self->path;
13668}
13669
Victor Stinner6036e442015-03-08 01:58:04 +010013670static PyMemberDef DirEntry_members[] = {
13671 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13672 "the entry's base filename, relative to scandir() \"path\" argument"},
13673 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13674 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13675 {NULL}
13676};
13677
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013678#include "clinic/posixmodule.c.h"
13679
Victor Stinner6036e442015-03-08 01:58:04 +010013680static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013681 OS_DIRENTRY_IS_DIR_METHODDEF
13682 OS_DIRENTRY_IS_FILE_METHODDEF
13683 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13684 OS_DIRENTRY_STAT_METHODDEF
13685 OS_DIRENTRY_INODE_METHODDEF
13686 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013687 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13688 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013689 {NULL}
13690};
13691
Eddie Elizondob3966632019-11-05 07:16:14 -080013692static PyType_Slot DirEntryType_slots[] = {
13693 {Py_tp_new, _disabled_new},
13694 {Py_tp_dealloc, DirEntry_dealloc},
13695 {Py_tp_repr, DirEntry_repr},
13696 {Py_tp_methods, DirEntry_methods},
13697 {Py_tp_members, DirEntry_members},
13698 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013699};
13700
Eddie Elizondob3966632019-11-05 07:16:14 -080013701static PyType_Spec DirEntryType_spec = {
13702 MODNAME ".DirEntry",
13703 sizeof(DirEntry),
13704 0,
13705 Py_TPFLAGS_DEFAULT,
13706 DirEntryType_slots
13707};
13708
13709
Victor Stinner6036e442015-03-08 01:58:04 +010013710#ifdef MS_WINDOWS
13711
13712static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013713join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013714{
13715 Py_ssize_t path_len;
13716 Py_ssize_t size;
13717 wchar_t *result;
13718 wchar_t ch;
13719
13720 if (!path_wide) { /* Default arg: "." */
13721 path_wide = L".";
13722 path_len = 1;
13723 }
13724 else {
13725 path_len = wcslen(path_wide);
13726 }
13727
13728 /* The +1's are for the path separator and the NUL */
13729 size = path_len + 1 + wcslen(filename) + 1;
13730 result = PyMem_New(wchar_t, size);
13731 if (!result) {
13732 PyErr_NoMemory();
13733 return NULL;
13734 }
13735 wcscpy(result, path_wide);
13736 if (path_len > 0) {
13737 ch = result[path_len - 1];
13738 if (ch != SEP && ch != ALTSEP && ch != L':')
13739 result[path_len++] = SEP;
13740 wcscpy(result + path_len, filename);
13741 }
13742 return result;
13743}
13744
13745static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013746DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013747{
13748 DirEntry *entry;
13749 BY_HANDLE_FILE_INFORMATION file_info;
13750 ULONG reparse_tag;
13751 wchar_t *joined_path;
13752
Victor Stinner1c2fa782020-05-10 11:05:29 +020013753 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013754 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013755 if (!entry)
13756 return NULL;
13757 entry->name = NULL;
13758 entry->path = NULL;
13759 entry->stat = NULL;
13760 entry->lstat = NULL;
13761 entry->got_file_index = 0;
13762
13763 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13764 if (!entry->name)
13765 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013766 if (path->narrow) {
13767 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13768 if (!entry->name)
13769 goto error;
13770 }
Victor Stinner6036e442015-03-08 01:58:04 +010013771
13772 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13773 if (!joined_path)
13774 goto error;
13775
13776 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13777 PyMem_Free(joined_path);
13778 if (!entry->path)
13779 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013780 if (path->narrow) {
13781 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13782 if (!entry->path)
13783 goto error;
13784 }
Victor Stinner6036e442015-03-08 01:58:04 +010013785
Steve Dowercc16be82016-09-08 10:35:16 -070013786 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013787 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13788
13789 return (PyObject *)entry;
13790
13791error:
13792 Py_DECREF(entry);
13793 return NULL;
13794}
13795
13796#else /* POSIX */
13797
13798static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013799join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013800{
13801 Py_ssize_t path_len;
13802 Py_ssize_t size;
13803 char *result;
13804
13805 if (!path_narrow) { /* Default arg: "." */
13806 path_narrow = ".";
13807 path_len = 1;
13808 }
13809 else {
13810 path_len = strlen(path_narrow);
13811 }
13812
13813 if (filename_len == -1)
13814 filename_len = strlen(filename);
13815
13816 /* The +1's are for the path separator and the NUL */
13817 size = path_len + 1 + filename_len + 1;
13818 result = PyMem_New(char, size);
13819 if (!result) {
13820 PyErr_NoMemory();
13821 return NULL;
13822 }
13823 strcpy(result, path_narrow);
13824 if (path_len > 0 && result[path_len - 1] != '/')
13825 result[path_len++] = '/';
13826 strcpy(result + path_len, filename);
13827 return result;
13828}
13829
13830static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013831DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13832 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013833#ifdef HAVE_DIRENT_D_TYPE
13834 , unsigned char d_type
13835#endif
13836 )
Victor Stinner6036e442015-03-08 01:58:04 +010013837{
13838 DirEntry *entry;
13839 char *joined_path;
13840
Victor Stinner1c2fa782020-05-10 11:05:29 +020013841 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013842 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013843 if (!entry)
13844 return NULL;
13845 entry->name = NULL;
13846 entry->path = NULL;
13847 entry->stat = NULL;
13848 entry->lstat = NULL;
13849
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013850 if (path->fd != -1) {
13851 entry->dir_fd = path->fd;
13852 joined_path = NULL;
13853 }
13854 else {
13855 entry->dir_fd = DEFAULT_DIR_FD;
13856 joined_path = join_path_filename(path->narrow, name, name_len);
13857 if (!joined_path)
13858 goto error;
13859 }
Victor Stinner6036e442015-03-08 01:58:04 +010013860
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013861 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013862 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013863 if (joined_path)
13864 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013865 }
13866 else {
13867 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013868 if (joined_path)
13869 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013870 }
13871 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013872 if (!entry->name)
13873 goto error;
13874
13875 if (path->fd != -1) {
13876 entry->path = entry->name;
13877 Py_INCREF(entry->path);
13878 }
13879 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013880 goto error;
13881
Victor Stinner35a97c02015-03-08 02:59:09 +010013882#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013883 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013884#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013885 entry->d_ino = d_ino;
13886
13887 return (PyObject *)entry;
13888
13889error:
13890 Py_XDECREF(entry);
13891 return NULL;
13892}
13893
13894#endif
13895
13896
13897typedef struct {
13898 PyObject_HEAD
13899 path_t path;
13900#ifdef MS_WINDOWS
13901 HANDLE handle;
13902 WIN32_FIND_DATAW file_data;
13903 int first_time;
13904#else /* POSIX */
13905 DIR *dirp;
13906#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013907#ifdef HAVE_FDOPENDIR
13908 int fd;
13909#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013910} ScandirIterator;
13911
13912#ifdef MS_WINDOWS
13913
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013914static int
13915ScandirIterator_is_closed(ScandirIterator *iterator)
13916{
13917 return iterator->handle == INVALID_HANDLE_VALUE;
13918}
13919
Victor Stinner6036e442015-03-08 01:58:04 +010013920static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013921ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013922{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013923 HANDLE handle = iterator->handle;
13924
13925 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013926 return;
13927
Victor Stinner6036e442015-03-08 01:58:04 +010013928 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013929 Py_BEGIN_ALLOW_THREADS
13930 FindClose(handle);
13931 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013932}
13933
13934static PyObject *
13935ScandirIterator_iternext(ScandirIterator *iterator)
13936{
13937 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13938 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013939 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013940
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013941 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013942 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013943 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013944
13945 while (1) {
13946 if (!iterator->first_time) {
13947 Py_BEGIN_ALLOW_THREADS
13948 success = FindNextFileW(iterator->handle, file_data);
13949 Py_END_ALLOW_THREADS
13950 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013951 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013952 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013953 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013954 break;
13955 }
13956 }
13957 iterator->first_time = 0;
13958
13959 /* Skip over . and .. */
13960 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020013961 wcscmp(file_data->cFileName, L"..") != 0)
13962 {
13963 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13964 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013965 if (!entry)
13966 break;
13967 return entry;
13968 }
Victor Stinner6036e442015-03-08 01:58:04 +010013969
13970 /* Loop till we get a non-dot directory or finish iterating */
13971 }
13972
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013973 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013974 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013975 return NULL;
13976}
13977
13978#else /* POSIX */
13979
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013980static int
13981ScandirIterator_is_closed(ScandirIterator *iterator)
13982{
13983 return !iterator->dirp;
13984}
13985
Victor Stinner6036e442015-03-08 01:58:04 +010013986static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013987ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013988{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013989 DIR *dirp = iterator->dirp;
13990
13991 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013992 return;
13993
Victor Stinner6036e442015-03-08 01:58:04 +010013994 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013995 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013996#ifdef HAVE_FDOPENDIR
13997 if (iterator->path.fd != -1)
13998 rewinddir(dirp);
13999#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014000 closedir(dirp);
14001 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010014002 return;
14003}
14004
14005static PyObject *
14006ScandirIterator_iternext(ScandirIterator *iterator)
14007{
14008 struct dirent *direntp;
14009 Py_ssize_t name_len;
14010 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014011 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014012
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014013 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014014 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010014015 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014016
14017 while (1) {
14018 errno = 0;
14019 Py_BEGIN_ALLOW_THREADS
14020 direntp = readdir(iterator->dirp);
14021 Py_END_ALLOW_THREADS
14022
14023 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014024 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010014025 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014026 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010014027 break;
14028 }
14029
14030 /* Skip over . and .. */
14031 name_len = NAMLEN(direntp);
14032 is_dot = direntp->d_name[0] == '.' &&
14033 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
14034 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014035 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
14036 entry = DirEntry_from_posix_info(module,
14037 &iterator->path, direntp->d_name,
14038 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010014039#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020014040 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010014041#endif
14042 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014043 if (!entry)
14044 break;
14045 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014046 }
14047
14048 /* Loop till we get a non-dot directory or finish iterating */
14049 }
14050
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014051 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014052 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010014053 return NULL;
14054}
14055
14056#endif
14057
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014058static PyObject *
14059ScandirIterator_close(ScandirIterator *self, PyObject *args)
14060{
14061 ScandirIterator_closedir(self);
14062 Py_RETURN_NONE;
14063}
14064
14065static PyObject *
14066ScandirIterator_enter(PyObject *self, PyObject *args)
14067{
14068 Py_INCREF(self);
14069 return self;
14070}
14071
14072static PyObject *
14073ScandirIterator_exit(ScandirIterator *self, PyObject *args)
14074{
14075 ScandirIterator_closedir(self);
14076 Py_RETURN_NONE;
14077}
14078
Victor Stinner6036e442015-03-08 01:58:04 +010014079static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010014080ScandirIterator_finalize(ScandirIterator *iterator)
14081{
14082 PyObject *error_type, *error_value, *error_traceback;
14083
14084 /* Save the current exception, if any. */
14085 PyErr_Fetch(&error_type, &error_value, &error_traceback);
14086
14087 if (!ScandirIterator_is_closed(iterator)) {
14088 ScandirIterator_closedir(iterator);
14089
14090 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
14091 "unclosed scandir iterator %R", iterator)) {
14092 /* Spurious errors can appear at shutdown */
14093 if (PyErr_ExceptionMatches(PyExc_Warning)) {
14094 PyErr_WriteUnraisable((PyObject *) iterator);
14095 }
14096 }
14097 }
14098
Victor Stinner7bfa4092016-03-23 00:43:54 +010014099 path_cleanup(&iterator->path);
14100
14101 /* Restore the saved exception. */
14102 PyErr_Restore(error_type, error_value, error_traceback);
14103}
14104
14105static void
Victor Stinner6036e442015-03-08 01:58:04 +010014106ScandirIterator_dealloc(ScandirIterator *iterator)
14107{
Eddie Elizondob3966632019-11-05 07:16:14 -080014108 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010014109 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
14110 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014111
Eddie Elizondob3966632019-11-05 07:16:14 -080014112 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
14113 free_func(iterator);
14114 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010014115}
14116
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014117static PyMethodDef ScandirIterator_methods[] = {
14118 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
14119 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
14120 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
14121 {NULL}
14122};
14123
Eddie Elizondob3966632019-11-05 07:16:14 -080014124static PyType_Slot ScandirIteratorType_slots[] = {
14125 {Py_tp_new, _disabled_new},
14126 {Py_tp_dealloc, ScandirIterator_dealloc},
14127 {Py_tp_finalize, ScandirIterator_finalize},
14128 {Py_tp_iter, PyObject_SelfIter},
14129 {Py_tp_iternext, ScandirIterator_iternext},
14130 {Py_tp_methods, ScandirIterator_methods},
14131 {0, 0},
14132};
14133
14134static PyType_Spec ScandirIteratorType_spec = {
14135 MODNAME ".ScandirIterator",
14136 sizeof(ScandirIterator),
14137 0,
Victor Stinner97f33c32020-05-14 18:05:58 +020014138 // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
14139 // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
Eddie Elizondob3966632019-11-05 07:16:14 -080014140 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
14141 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010014142};
14143
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014144/*[clinic input]
14145os.scandir
14146
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014147 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014148
14149Return an iterator of DirEntry objects for given path.
14150
BNMetricsb9427072018-11-02 15:20:19 +000014151path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014152is bytes, the names of yielded DirEntry objects will also be bytes; in
14153all other circumstances they will be str.
14154
14155If path is None, uses the path='.'.
14156[clinic start generated code]*/
14157
Victor Stinner6036e442015-03-08 01:58:04 +010014158static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014159os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000014160/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010014161{
14162 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010014163#ifdef MS_WINDOWS
14164 wchar_t *path_strW;
14165#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014166 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014167#ifdef HAVE_FDOPENDIR
14168 int fd = -1;
14169#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014170#endif
14171
Steve Dower60419a72019-06-24 08:42:54 -070014172 if (PySys_Audit("os.scandir", "O",
14173 path->object ? path->object : Py_None) < 0) {
14174 return NULL;
14175 }
14176
Hai Shif707d942020-03-16 21:15:01 +080014177 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014178 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010014179 if (!iterator)
14180 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014181
14182#ifdef MS_WINDOWS
14183 iterator->handle = INVALID_HANDLE_VALUE;
14184#else
14185 iterator->dirp = NULL;
14186#endif
14187
Serhiy Storchaka095ef732017-02-09 20:05:51 +020014188 /* Move the ownership to iterator->path */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014189 memcpy(&iterator->path, path, sizeof(path_t));
14190 memset(path, 0, sizeof(path_t));
Victor Stinner6036e442015-03-08 01:58:04 +010014191
14192#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010014193 iterator->first_time = 1;
14194
14195 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
14196 if (!path_strW)
14197 goto error;
14198
14199 Py_BEGIN_ALLOW_THREADS
14200 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
14201 Py_END_ALLOW_THREADS
14202
14203 PyMem_Free(path_strW);
14204
14205 if (iterator->handle == INVALID_HANDLE_VALUE) {
14206 path_error(&iterator->path);
14207 goto error;
14208 }
14209#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010014210 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014211#ifdef HAVE_FDOPENDIR
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014212 if (iterator->path.fd != -1) {
Ronald Oussoren41761932020-11-08 10:05:27 +010014213 if (HAVE_FDOPENDIR_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014214 /* closedir() closes the FD, so we duplicate it */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014215 fd = _Py_dup(iterator->path.fd);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014216 if (fd == -1)
14217 goto error;
14218
14219 Py_BEGIN_ALLOW_THREADS
14220 iterator->dirp = fdopendir(fd);
14221 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +010014222 } else {
14223 PyErr_SetString(PyExc_TypeError,
14224 "scandir: path should be string, bytes, os.PathLike or None, not int");
14225 return NULL;
14226 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014227 }
14228 else
14229#endif
14230 {
14231 if (iterator->path.narrow)
14232 path_str = iterator->path.narrow;
14233 else
14234 path_str = ".";
14235
14236 Py_BEGIN_ALLOW_THREADS
14237 iterator->dirp = opendir(path_str);
14238 Py_END_ALLOW_THREADS
14239 }
Victor Stinner6036e442015-03-08 01:58:04 +010014240
14241 if (!iterator->dirp) {
14242 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014243#ifdef HAVE_FDOPENDIR
14244 if (fd != -1) {
14245 Py_BEGIN_ALLOW_THREADS
14246 close(fd);
14247 Py_END_ALLOW_THREADS
14248 }
14249#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014250 goto error;
14251 }
14252#endif
14253
14254 return (PyObject *)iterator;
14255
14256error:
14257 Py_DECREF(iterator);
14258 return NULL;
14259}
14260
Ethan Furman410ef8e2016-06-04 12:06:26 -070014261/*
14262 Return the file system path representation of the object.
14263
14264 If the object is str or bytes, then allow it to pass through with
14265 an incremented refcount. If the object defines __fspath__(), then
14266 return the result of that method. All other types raise a TypeError.
14267*/
14268PyObject *
14269PyOS_FSPath(PyObject *path)
14270{
Brett Cannon3f9183b2016-08-26 14:44:48 -070014271 /* For error message reasons, this function is manually inlined in
14272 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070014273 PyObject *func = NULL;
14274 PyObject *path_repr = NULL;
14275
14276 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
14277 Py_INCREF(path);
14278 return path;
14279 }
14280
14281 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
14282 if (NULL == func) {
14283 return PyErr_Format(PyExc_TypeError,
14284 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014285 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080014286 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070014287 }
14288
Victor Stinnerf17c3de2016-12-06 18:46:19 +010014289 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070014290 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070014291 if (NULL == path_repr) {
14292 return NULL;
14293 }
14294
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014295 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
14296 PyErr_Format(PyExc_TypeError,
14297 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080014298 "not %.200s", _PyType_Name(Py_TYPE(path)),
14299 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014300 Py_DECREF(path_repr);
14301 return NULL;
14302 }
14303
Ethan Furman410ef8e2016-06-04 12:06:26 -070014304 return path_repr;
14305}
14306
14307/*[clinic input]
14308os.fspath
14309
14310 path: object
14311
14312Return the file system path representation of the object.
14313
Brett Cannonb4f43e92016-06-09 14:32:08 -070014314If the object is str or bytes, then allow it to pass through as-is. If the
14315object defines __fspath__(), then return the result of that method. All other
14316types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070014317[clinic start generated code]*/
14318
14319static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030014320os_fspath_impl(PyObject *module, PyObject *path)
14321/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070014322{
14323 return PyOS_FSPath(path);
14324}
Victor Stinner6036e442015-03-08 01:58:04 +010014325
Victor Stinner9b1f4742016-09-06 16:18:52 -070014326#ifdef HAVE_GETRANDOM_SYSCALL
14327/*[clinic input]
14328os.getrandom
14329
14330 size: Py_ssize_t
14331 flags: int=0
14332
14333Obtain a series of random bytes.
14334[clinic start generated code]*/
14335
14336static PyObject *
14337os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
14338/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
14339{
Victor Stinner9b1f4742016-09-06 16:18:52 -070014340 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014341 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014342
14343 if (size < 0) {
14344 errno = EINVAL;
14345 return posix_error();
14346 }
14347
Victor Stinnerec2319c2016-09-20 23:00:59 +020014348 bytes = PyBytes_FromStringAndSize(NULL, size);
14349 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014350 PyErr_NoMemory();
14351 return NULL;
14352 }
14353
14354 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014355 n = syscall(SYS_getrandom,
14356 PyBytes_AS_STRING(bytes),
14357 PyBytes_GET_SIZE(bytes),
14358 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070014359 if (n < 0 && errno == EINTR) {
14360 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014361 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014362 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020014363
14364 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070014365 continue;
14366 }
14367 break;
14368 }
14369
14370 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014371 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020014372 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014373 }
14374
Victor Stinnerec2319c2016-09-20 23:00:59 +020014375 if (n != size) {
14376 _PyBytes_Resize(&bytes, n);
14377 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070014378
14379 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014380
14381error:
14382 Py_DECREF(bytes);
14383 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014384}
14385#endif /* HAVE_GETRANDOM_SYSCALL */
14386
Steve Dower2438cdf2019-03-29 16:37:16 -070014387#ifdef MS_WINDOWS
14388/* bpo-36085: Helper functions for managing DLL search directories
14389 * on win32
14390 */
14391
14392typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
14393typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
14394
14395/*[clinic input]
14396os._add_dll_directory
14397
14398 path: path_t
14399
14400Add a path to the DLL search path.
14401
14402This search path is used when resolving dependencies for imported
14403extension modules (the module itself is resolved through sys.path),
14404and also by ctypes.
14405
14406Returns an opaque value that may be passed to os.remove_dll_directory
14407to remove this directory from the search path.
14408[clinic start generated code]*/
14409
14410static PyObject *
14411os__add_dll_directory_impl(PyObject *module, path_t *path)
14412/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
14413{
14414 HMODULE hKernel32;
14415 PAddDllDirectory AddDllDirectory;
14416 DLL_DIRECTORY_COOKIE cookie = 0;
14417 DWORD err = 0;
14418
Saiyang Gou7514f4f2020-02-12 23:47:42 -080014419 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
14420 return NULL;
14421 }
14422
Steve Dower2438cdf2019-03-29 16:37:16 -070014423 /* For Windows 7, we have to load this. As this will be a fairly
14424 infrequent operation, just do it each time. Kernel32 is always
14425 loaded. */
14426 Py_BEGIN_ALLOW_THREADS
14427 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14428 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
14429 hKernel32, "AddDllDirectory")) ||
14430 !(cookie = (*AddDllDirectory)(path->wide))) {
14431 err = GetLastError();
14432 }
14433 Py_END_ALLOW_THREADS
14434
14435 if (err) {
14436 return win32_error_object_err("add_dll_directory",
14437 path->object, err);
14438 }
14439
14440 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
14441}
14442
14443/*[clinic input]
14444os._remove_dll_directory
14445
14446 cookie: object
14447
14448Removes a path from the DLL search path.
14449
14450The parameter is an opaque value that was returned from
14451os.add_dll_directory. You can only remove directories that you added
14452yourself.
14453[clinic start generated code]*/
14454
14455static PyObject *
14456os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
14457/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
14458{
14459 HMODULE hKernel32;
14460 PRemoveDllDirectory RemoveDllDirectory;
14461 DLL_DIRECTORY_COOKIE cookieValue;
14462 DWORD err = 0;
14463
14464 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
14465 PyErr_SetString(PyExc_TypeError,
14466 "Provided cookie was not returned from os.add_dll_directory");
14467 return NULL;
14468 }
14469
14470 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
14471 cookie, "DLL directory cookie");
14472
14473 /* For Windows 7, we have to load this. As this will be a fairly
14474 infrequent operation, just do it each time. Kernel32 is always
14475 loaded. */
14476 Py_BEGIN_ALLOW_THREADS
14477 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14478 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
14479 hKernel32, "RemoveDllDirectory")) ||
14480 !(*RemoveDllDirectory)(cookieValue)) {
14481 err = GetLastError();
14482 }
14483 Py_END_ALLOW_THREADS
14484
14485 if (err) {
14486 return win32_error_object_err("remove_dll_directory",
14487 NULL, err);
14488 }
14489
14490 if (PyCapsule_SetName(cookie, NULL)) {
14491 return NULL;
14492 }
14493
14494 Py_RETURN_NONE;
14495}
14496
14497#endif
Larry Hastings31826802013-10-19 00:09:25 -070014498
Victor Stinner65a796e2020-04-01 18:49:29 +020014499
14500/* Only check if WIFEXITED is available: expect that it comes
14501 with WEXITSTATUS, WIFSIGNALED, etc.
14502
14503 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
14504 subprocess can safely call it during late Python finalization without
Victor Stinner62230712020-11-18 23:18:29 +010014505 risking that used os attributes were set to None by finalize_modules(). */
Victor Stinner65a796e2020-04-01 18:49:29 +020014506#if defined(WIFEXITED) || defined(MS_WINDOWS)
14507/*[clinic input]
14508os.waitstatus_to_exitcode
14509
Victor Stinner9bee32b2020-04-22 16:30:35 +020014510 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020014511
14512Convert a wait status to an exit code.
14513
14514On Unix:
14515
14516* If WIFEXITED(status) is true, return WEXITSTATUS(status).
14517* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
14518* Otherwise, raise a ValueError.
14519
14520On Windows, return status shifted right by 8 bits.
14521
14522On Unix, if the process is being traced or if waitpid() was called with
14523WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
14524This function must not be called if WIFSTOPPED(status) is true.
14525[clinic start generated code]*/
14526
14527static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020014528os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
14529/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020014530{
14531#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020014532 int status = _PyLong_AsInt(status_obj);
14533 if (status == -1 && PyErr_Occurred()) {
14534 return NULL;
14535 }
14536
Victor Stinner65a796e2020-04-01 18:49:29 +020014537 WAIT_TYPE wait_status;
14538 WAIT_STATUS_INT(wait_status) = status;
14539 int exitcode;
14540 if (WIFEXITED(wait_status)) {
14541 exitcode = WEXITSTATUS(wait_status);
14542 /* Sanity check to provide warranty on the function behavior.
14543 It should not occur in practice */
14544 if (exitcode < 0) {
14545 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
14546 return NULL;
14547 }
14548 }
14549 else if (WIFSIGNALED(wait_status)) {
14550 int signum = WTERMSIG(wait_status);
14551 /* Sanity check to provide warranty on the function behavior.
14552 It should not occurs in practice */
14553 if (signum <= 0) {
14554 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
14555 return NULL;
14556 }
14557 exitcode = -signum;
14558 } else if (WIFSTOPPED(wait_status)) {
14559 /* Status only received if the process is being traced
14560 or if waitpid() was called with WUNTRACED option. */
14561 int signum = WSTOPSIG(wait_status);
14562 PyErr_Format(PyExc_ValueError,
14563 "process stopped by delivery of signal %i",
14564 signum);
14565 return NULL;
14566 }
14567 else {
14568 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
14569 return NULL;
14570 }
14571 return PyLong_FromLong(exitcode);
14572#else
14573 /* Windows implementation: see os.waitpid() implementation
14574 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020014575 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
14576 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
14577 return NULL;
14578 }
14579
14580 unsigned long long exitcode = (status >> 8);
14581 /* ExitProcess() accepts an UINT type:
14582 reject exit code which doesn't fit in an UINT */
14583 if (exitcode > UINT_MAX) {
14584 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
14585 return NULL;
14586 }
14587 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020014588#endif
14589}
14590#endif
14591
14592
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014593static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070014594
14595 OS_STAT_METHODDEF
14596 OS_ACCESS_METHODDEF
14597 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014598 OS_CHDIR_METHODDEF
14599 OS_CHFLAGS_METHODDEF
14600 OS_CHMOD_METHODDEF
14601 OS_FCHMOD_METHODDEF
14602 OS_LCHMOD_METHODDEF
14603 OS_CHOWN_METHODDEF
14604 OS_FCHOWN_METHODDEF
14605 OS_LCHOWN_METHODDEF
14606 OS_LCHFLAGS_METHODDEF
14607 OS_CHROOT_METHODDEF
14608 OS_CTERMID_METHODDEF
14609 OS_GETCWD_METHODDEF
14610 OS_GETCWDB_METHODDEF
14611 OS_LINK_METHODDEF
14612 OS_LISTDIR_METHODDEF
14613 OS_LSTAT_METHODDEF
14614 OS_MKDIR_METHODDEF
14615 OS_NICE_METHODDEF
14616 OS_GETPRIORITY_METHODDEF
14617 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014618 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030014619 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014620 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010014621 OS_COPY_FILE_RANGE_METHODDEF
Pablo Galindoa57b3d32020-11-17 00:00:38 +000014622 OS_SPLICE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014623 OS_RENAME_METHODDEF
14624 OS_REPLACE_METHODDEF
14625 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014626 OS_SYMLINK_METHODDEF
14627 OS_SYSTEM_METHODDEF
14628 OS_UMASK_METHODDEF
14629 OS_UNAME_METHODDEF
14630 OS_UNLINK_METHODDEF
14631 OS_REMOVE_METHODDEF
14632 OS_UTIME_METHODDEF
14633 OS_TIMES_METHODDEF
14634 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014635 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014636 OS_EXECV_METHODDEF
14637 OS_EXECVE_METHODDEF
14638 OS_SPAWNV_METHODDEF
14639 OS_SPAWNVE_METHODDEF
14640 OS_FORK1_METHODDEF
14641 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014642 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014643 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14644 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14645 OS_SCHED_GETPARAM_METHODDEF
14646 OS_SCHED_GETSCHEDULER_METHODDEF
14647 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14648 OS_SCHED_SETPARAM_METHODDEF
14649 OS_SCHED_SETSCHEDULER_METHODDEF
14650 OS_SCHED_YIELD_METHODDEF
14651 OS_SCHED_SETAFFINITY_METHODDEF
14652 OS_SCHED_GETAFFINITY_METHODDEF
14653 OS_OPENPTY_METHODDEF
14654 OS_FORKPTY_METHODDEF
14655 OS_GETEGID_METHODDEF
14656 OS_GETEUID_METHODDEF
14657 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014658 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014659 OS_GETGROUPS_METHODDEF
14660 OS_GETPID_METHODDEF
14661 OS_GETPGRP_METHODDEF
14662 OS_GETPPID_METHODDEF
14663 OS_GETUID_METHODDEF
14664 OS_GETLOGIN_METHODDEF
14665 OS_KILL_METHODDEF
14666 OS_KILLPG_METHODDEF
14667 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014668 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014669 OS_SETUID_METHODDEF
14670 OS_SETEUID_METHODDEF
14671 OS_SETREUID_METHODDEF
14672 OS_SETGID_METHODDEF
14673 OS_SETEGID_METHODDEF
14674 OS_SETREGID_METHODDEF
14675 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014676 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014677 OS_GETPGID_METHODDEF
14678 OS_SETPGRP_METHODDEF
14679 OS_WAIT_METHODDEF
14680 OS_WAIT3_METHODDEF
14681 OS_WAIT4_METHODDEF
14682 OS_WAITID_METHODDEF
14683 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014684 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014685 OS_GETSID_METHODDEF
14686 OS_SETSID_METHODDEF
14687 OS_SETPGID_METHODDEF
14688 OS_TCGETPGRP_METHODDEF
14689 OS_TCSETPGRP_METHODDEF
14690 OS_OPEN_METHODDEF
14691 OS_CLOSE_METHODDEF
14692 OS_CLOSERANGE_METHODDEF
14693 OS_DEVICE_ENCODING_METHODDEF
14694 OS_DUP_METHODDEF
14695 OS_DUP2_METHODDEF
14696 OS_LOCKF_METHODDEF
14697 OS_LSEEK_METHODDEF
14698 OS_READ_METHODDEF
14699 OS_READV_METHODDEF
14700 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014701 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014702 OS_WRITE_METHODDEF
14703 OS_WRITEV_METHODDEF
14704 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014705 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014706 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014707 OS_FSTAT_METHODDEF
14708 OS_ISATTY_METHODDEF
14709 OS_PIPE_METHODDEF
14710 OS_PIPE2_METHODDEF
14711 OS_MKFIFO_METHODDEF
14712 OS_MKNOD_METHODDEF
14713 OS_MAJOR_METHODDEF
14714 OS_MINOR_METHODDEF
14715 OS_MAKEDEV_METHODDEF
14716 OS_FTRUNCATE_METHODDEF
14717 OS_TRUNCATE_METHODDEF
14718 OS_POSIX_FALLOCATE_METHODDEF
14719 OS_POSIX_FADVISE_METHODDEF
14720 OS_PUTENV_METHODDEF
14721 OS_UNSETENV_METHODDEF
14722 OS_STRERROR_METHODDEF
14723 OS_FCHDIR_METHODDEF
14724 OS_FSYNC_METHODDEF
14725 OS_SYNC_METHODDEF
14726 OS_FDATASYNC_METHODDEF
14727 OS_WCOREDUMP_METHODDEF
14728 OS_WIFCONTINUED_METHODDEF
14729 OS_WIFSTOPPED_METHODDEF
14730 OS_WIFSIGNALED_METHODDEF
14731 OS_WIFEXITED_METHODDEF
14732 OS_WEXITSTATUS_METHODDEF
14733 OS_WTERMSIG_METHODDEF
14734 OS_WSTOPSIG_METHODDEF
14735 OS_FSTATVFS_METHODDEF
14736 OS_STATVFS_METHODDEF
14737 OS_CONFSTR_METHODDEF
14738 OS_SYSCONF_METHODDEF
14739 OS_FPATHCONF_METHODDEF
14740 OS_PATHCONF_METHODDEF
14741 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014742 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014743 OS__GETDISKUSAGE_METHODDEF
14744 OS__GETFINALPATHNAME_METHODDEF
14745 OS__GETVOLUMEPATHNAME_METHODDEF
14746 OS_GETLOADAVG_METHODDEF
14747 OS_URANDOM_METHODDEF
14748 OS_SETRESUID_METHODDEF
14749 OS_SETRESGID_METHODDEF
14750 OS_GETRESUID_METHODDEF
14751 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014752
Larry Hastings2f936352014-08-05 14:04:04 +100014753 OS_GETXATTR_METHODDEF
14754 OS_SETXATTR_METHODDEF
14755 OS_REMOVEXATTR_METHODDEF
14756 OS_LISTXATTR_METHODDEF
14757
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014758 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014759 OS_CPU_COUNT_METHODDEF
14760 OS_GET_INHERITABLE_METHODDEF
14761 OS_SET_INHERITABLE_METHODDEF
14762 OS_GET_HANDLE_INHERITABLE_METHODDEF
14763 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014764 OS_GET_BLOCKING_METHODDEF
14765 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014766 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014767 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014768 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014769 OS_MEMFD_CREATE_METHODDEF
Christian Heimescd9fed62020-11-13 19:48:52 +010014770 OS_EVENTFD_METHODDEF
14771 OS_EVENTFD_READ_METHODDEF
14772 OS_EVENTFD_WRITE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014773 OS__ADD_DLL_DIRECTORY_METHODDEF
14774 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014775 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014776 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014777};
14778
Barry Warsaw4a342091996-12-19 23:50:02 +000014779static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014780all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014781{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014782#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014783 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014784#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014785#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014786 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014787#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014788#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014789 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014790#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014791#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014792 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014793#endif
Fred Drakec9680921999-12-13 16:37:25 +000014794#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014795 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014796#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014797#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014798 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014799#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014800#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014801 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014802#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014803#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014804 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014805#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014806#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014807 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014808#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014809#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014810 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014811#endif
14812#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014813 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014814#endif
14815#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014816 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014817#endif
14818#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014819 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014820#endif
14821#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014822 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014823#endif
14824#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014825 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014826#endif
14827#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014828 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014829#endif
14830#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014831 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014832#endif
14833#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014834 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014835#endif
14836#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014837 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014838#endif
14839#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014840 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014841#endif
14842#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014843 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014844#endif
14845#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014846 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014847#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014848#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014849 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014850#endif
14851#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014852 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014853#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014854#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014855 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014856#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014857#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014858 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014859#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014860#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014861#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014862 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014863#endif
14864#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014865 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014866#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014867#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014868#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014869 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014870#endif
14871#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014872 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014873#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014874#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014875 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014876#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014877#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014878 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014879#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014880#ifdef O_TMPFILE
14881 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14882#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014883#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014884 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014885#endif
14886#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014887 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014888#endif
14889#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014890 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014891#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014892#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014893 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014894#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014895#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014896 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014897#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014898
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014899
Jesus Cea94363612012-06-22 18:32:07 +020014900#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014901 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014902#endif
14903#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014904 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014905#endif
14906
Tim Peters5aa91602002-01-30 05:46:57 +000014907/* MS Windows */
14908#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014909 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014910 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014911#endif
14912#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000014913 /* Optimize for short life (keep in memory). */
14914 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014915 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014916#endif
14917#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000014918 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014919 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014920#endif
14921#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000014922 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014923 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014924#endif
14925#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014926 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014927 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014928#endif
14929
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014930/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014931#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014932 /* Send a SIGIO signal whenever input or output
14933 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014934 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014935#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014936#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014937 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014938 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014939#endif
14940#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000014941 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014942 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014943#endif
14944#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000014945 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014946 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014947#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014948#ifdef O_NOLINKS
14949 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014950 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014951#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014952#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014953 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014954 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014955#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000014956
Victor Stinner8c62be82010-05-06 00:08:46 +000014957 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014958#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014959 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014960#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014961#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014962 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014963#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014964#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014965 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014966#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014967#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014968 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014969#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014970#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014971 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014972#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014973#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014974 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014975#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014976#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014977 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014978#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014979#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014980 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014981#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014982#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014983 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014984#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014985#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014986 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014987#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014988#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014989 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014990#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014991#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014992 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014993#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014994#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014995 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014996#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014997#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014998 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014999#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015000#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015001 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015002#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015003#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015004 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015005#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015006#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015007 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015008#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015009
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000015010 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015011#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015012 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015013#endif /* ST_RDONLY */
15014#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015015 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015016#endif /* ST_NOSUID */
15017
doko@ubuntu.comca616a22013-12-08 15:23:07 +010015018 /* GNU extensions */
15019#ifdef ST_NODEV
15020 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
15021#endif /* ST_NODEV */
15022#ifdef ST_NOEXEC
15023 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
15024#endif /* ST_NOEXEC */
15025#ifdef ST_SYNCHRONOUS
15026 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
15027#endif /* ST_SYNCHRONOUS */
15028#ifdef ST_MANDLOCK
15029 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
15030#endif /* ST_MANDLOCK */
15031#ifdef ST_WRITE
15032 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
15033#endif /* ST_WRITE */
15034#ifdef ST_APPEND
15035 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
15036#endif /* ST_APPEND */
15037#ifdef ST_NOATIME
15038 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
15039#endif /* ST_NOATIME */
15040#ifdef ST_NODIRATIME
15041 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
15042#endif /* ST_NODIRATIME */
15043#ifdef ST_RELATIME
15044 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
15045#endif /* ST_RELATIME */
15046
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015047 /* FreeBSD sendfile() constants */
15048#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015049 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015050#endif
15051#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015052 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015053#endif
15054#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015055 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015056#endif
15057
Ross Lagerwall7807c352011-03-17 20:20:30 +020015058 /* constants for posix_fadvise */
15059#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015060 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015061#endif
15062#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015063 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015064#endif
15065#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015066 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015067#endif
15068#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015069 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015070#endif
15071#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015072 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015073#endif
15074#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015075 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015076#endif
15077
15078 /* constants for waitid */
15079#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015080 if (PyModule_AddIntMacro(m, P_PID)) return -1;
15081 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
15082 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080015083#ifdef P_PIDFD
15084 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
15085#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015086#endif
15087#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015088 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015089#endif
15090#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015091 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015092#endif
15093#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015094 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015095#endif
15096#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015097 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015098#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015099#ifdef CLD_KILLED
15100 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
15101#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015102#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015103 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015104#endif
15105#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015106 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015107#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015108#ifdef CLD_STOPPED
15109 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
15110#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015111#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015112 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015113#endif
15114
15115 /* constants for lockf */
15116#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015117 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015118#endif
15119#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015120 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015121#endif
15122#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015123 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015124#endif
15125#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015126 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015127#endif
15128
Pablo Galindo4defba32018-01-27 16:16:37 +000015129#ifdef RWF_DSYNC
15130 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
15131#endif
15132#ifdef RWF_HIPRI
15133 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
15134#endif
15135#ifdef RWF_SYNC
15136 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
15137#endif
15138#ifdef RWF_NOWAIT
15139 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
15140#endif
YoSTEALTH76ef2552020-05-27 15:32:22 -060015141#ifdef RWF_APPEND
15142 if (PyModule_AddIntConstant(m, "RWF_APPEND", RWF_APPEND)) return -1;
15143#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000015144
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015145/* constants for splice */
Pablo Galindo2a9eddf2020-11-17 19:57:49 +000015146#if defined(HAVE_SPLICE) && defined(__linux__)
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015147 if (PyModule_AddIntConstant(m, "SPLICE_F_MOVE", SPLICE_F_MOVE)) return -1;
15148 if (PyModule_AddIntConstant(m, "SPLICE_F_NONBLOCK", SPLICE_F_NONBLOCK)) return -1;
15149 if (PyModule_AddIntConstant(m, "SPLICE_F_MORE", SPLICE_F_MORE)) return -1;
15150#endif
15151
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000015152/* constants for posix_spawn */
15153#ifdef HAVE_POSIX_SPAWN
15154 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
15155 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
15156 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
15157#endif
15158
pxinwrf2d7ac72019-05-21 18:46:37 +080015159#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015160 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
15161 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015162 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080015163#endif
15164#ifdef HAVE_SPAWNV
15165 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015166 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000015167#endif
15168
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015169#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015170#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015171 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015172#endif
15173#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015174 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015175#endif
15176#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015177 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015178#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015179#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080015180 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015181#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015182#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015183 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015184#endif
15185#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015186 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015187#endif
15188#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015189 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015190#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015191#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015192 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015193#endif
15194#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015195 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015196#endif
15197#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015198 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015199#endif
15200#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015201 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015202#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015203#endif
15204
Benjamin Peterson9428d532011-09-14 11:45:52 -040015205#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015206 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
15207 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
15208 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015209#endif
15210
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015211#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015212 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015213#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015214#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015215 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015216#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015217#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015218 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015219#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015220#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015221 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015222#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015223#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015224 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015225#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015226#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015227 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015228#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015229#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015230 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015231#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010015232#if HAVE_DECL_RTLD_MEMBER
15233 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
15234#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020015235
Victor Stinner9b1f4742016-09-06 16:18:52 -070015236#ifdef HAVE_GETRANDOM_SYSCALL
15237 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
15238 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
15239#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015240#ifdef HAVE_MEMFD_CREATE
15241 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
15242 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
15243#ifdef MFD_HUGETLB
15244 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015245#endif
15246#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015247 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015248#endif
15249#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015250 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015251#endif
15252#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015253 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015254#endif
15255#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015256 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015257#endif
15258#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015259 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015260#endif
15261#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015262 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015263#endif
15264#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015265 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015266#endif
15267#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015268 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015269#endif
15270#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015271 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015272#endif
15273#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015274 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015275#endif
15276#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015277 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015278#endif
15279#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015280 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015281#endif
15282#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015283 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015284#endif
15285#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015286 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
15287#endif
Christian Heimescd9fed62020-11-13 19:48:52 +010015288#endif /* HAVE_MEMFD_CREATE */
15289
15290#ifdef HAVE_EVENTFD
15291 if (PyModule_AddIntMacro(m, EFD_CLOEXEC)) return -1;
15292 if (PyModule_AddIntMacro(m, EFD_NONBLOCK)) return -1;
15293 if (PyModule_AddIntMacro(m, EFD_SEMAPHORE)) return -1;
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015294#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070015295
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020015296#if defined(__APPLE__)
15297 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
15298#endif
15299
Steve Dower2438cdf2019-03-29 16:37:16 -070015300#ifdef MS_WINDOWS
15301 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
15302 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
15303 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
15304 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
15305 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
15306#endif
15307
Victor Stinner8c62be82010-05-06 00:08:46 +000015308 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000015309}
15310
15311
Ronald Oussoren41761932020-11-08 10:05:27 +010015312
15313#define PROBE(name, test) \
15314 static int name(void) \
15315 { \
15316 if (test) { \
15317 return 1; \
15318 } else { \
15319 return 0; \
15320 } \
15321 }
15322
15323#ifdef HAVE_FSTATAT
15324PROBE(probe_fstatat, HAVE_FSTATAT_RUNTIME)
15325#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070015326
15327#ifdef HAVE_FACCESSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015328PROBE(probe_faccessat, HAVE_FACCESSAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015329#endif
15330
15331#ifdef HAVE_FCHMODAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015332PROBE(probe_fchmodat, HAVE_FCHMODAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015333#endif
15334
Larry Hastings00964ed2013-08-12 13:49:30 -040015335#ifdef HAVE_FCHOWNAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015336PROBE(probe_fchownat, HAVE_FCHOWNAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015337#endif
15338
15339#ifdef HAVE_LINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015340PROBE(probe_linkat, HAVE_LINKAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015341#endif
15342
Ronald Oussoren41761932020-11-08 10:05:27 +010015343#ifdef HAVE_FDOPENDIR
15344PROBE(probe_fdopendir, HAVE_FDOPENDIR_RUNTIME)
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015345#endif
15346
Larry Hastings9cf065c2012-06-22 16:30:09 -070015347#ifdef HAVE_MKDIRAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015348PROBE(probe_mkdirat, HAVE_MKDIRAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015349#endif
15350
15351#ifdef HAVE_RENAMEAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015352PROBE(probe_renameat, HAVE_RENAMEAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015353#endif
15354
15355#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015356PROBE(probe_unlinkat, HAVE_UNLINKAT_RUNTIME)
15357#endif
15358
15359#ifdef HAVE_OPENAT
15360PROBE(probe_openat, HAVE_OPENAT_RUNTIME)
15361#endif
15362
15363#ifdef HAVE_READLINKAT
15364PROBE(probe_readlinkat, HAVE_READLINKAT_RUNTIME)
15365#endif
15366
15367#ifdef HAVE_SYMLINKAT
15368PROBE(probe_symlinkat, HAVE_SYMLINKAT_RUNTIME)
15369#endif
15370
15371#ifdef HAVE_FUTIMENS
15372PROBE(probe_futimens, HAVE_FUTIMENS_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015373#endif
15374
15375#ifdef HAVE_UTIMENSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015376PROBE(probe_utimensat, HAVE_UTIMENSAT_RUNTIME)
15377#endif
15378
15379
15380
15381
15382static const struct have_function {
15383 const char * const label;
15384 int (*probe)(void);
15385} have_functions[] = {
15386
Christian Heimescd9fed62020-11-13 19:48:52 +010015387#ifdef HAVE_EVENTFD
15388 {"HAVE_EVENTFD", NULL},
15389#endif
15390
Ronald Oussoren41761932020-11-08 10:05:27 +010015391#ifdef HAVE_FACCESSAT
15392 { "HAVE_FACCESSAT", probe_faccessat },
15393#endif
15394
15395#ifdef HAVE_FCHDIR
15396 { "HAVE_FCHDIR", NULL },
15397#endif
15398
15399#ifdef HAVE_FCHMOD
15400 { "HAVE_FCHMOD", NULL },
15401#endif
15402
15403#ifdef HAVE_FCHMODAT
15404 { "HAVE_FCHMODAT", probe_fchmodat },
15405#endif
15406
15407#ifdef HAVE_FCHOWN
15408 { "HAVE_FCHOWN", NULL },
15409#endif
15410
15411#ifdef HAVE_FCHOWNAT
15412 { "HAVE_FCHOWNAT", probe_fchownat },
15413#endif
15414
15415#ifdef HAVE_FEXECVE
15416 { "HAVE_FEXECVE", NULL },
15417#endif
15418
15419#ifdef HAVE_FDOPENDIR
15420 { "HAVE_FDOPENDIR", probe_fdopendir },
15421#endif
15422
15423#ifdef HAVE_FPATHCONF
15424 { "HAVE_FPATHCONF", NULL },
15425#endif
15426
15427#ifdef HAVE_FSTATAT
15428 { "HAVE_FSTATAT", probe_fstatat },
15429#endif
15430
15431#ifdef HAVE_FSTATVFS
15432 { "HAVE_FSTATVFS", NULL },
15433#endif
15434
15435#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
15436 { "HAVE_FTRUNCATE", NULL },
15437#endif
15438
15439#ifdef HAVE_FUTIMENS
15440 { "HAVE_FUTIMENS", probe_futimens },
15441#endif
15442
15443#ifdef HAVE_FUTIMES
15444 { "HAVE_FUTIMES", NULL },
15445#endif
15446
15447#ifdef HAVE_FUTIMESAT
15448 { "HAVE_FUTIMESAT", NULL },
15449#endif
15450
15451#ifdef HAVE_LINKAT
15452 { "HAVE_LINKAT", probe_linkat },
15453#endif
15454
15455#ifdef HAVE_LCHFLAGS
15456 { "HAVE_LCHFLAGS", NULL },
15457#endif
15458
15459#ifdef HAVE_LCHMOD
15460 { "HAVE_LCHMOD", NULL },
15461#endif
15462
15463#ifdef HAVE_LCHOWN
15464 { "HAVE_LCHOWN", NULL },
15465#endif
15466
15467#ifdef HAVE_LSTAT
15468 { "HAVE_LSTAT", NULL },
15469#endif
15470
15471#ifdef HAVE_LUTIMES
15472 { "HAVE_LUTIMES", NULL },
15473#endif
15474
15475#ifdef HAVE_MEMFD_CREATE
15476 { "HAVE_MEMFD_CREATE", NULL },
15477#endif
15478
15479#ifdef HAVE_MKDIRAT
15480 { "HAVE_MKDIRAT", probe_mkdirat },
15481#endif
15482
15483#ifdef HAVE_MKFIFOAT
15484 { "HAVE_MKFIFOAT", NULL },
15485#endif
15486
15487#ifdef HAVE_MKNODAT
15488 { "HAVE_MKNODAT", NULL },
15489#endif
15490
15491#ifdef HAVE_OPENAT
15492 { "HAVE_OPENAT", probe_openat },
15493#endif
15494
15495#ifdef HAVE_READLINKAT
15496 { "HAVE_READLINKAT", probe_readlinkat },
15497#endif
15498
15499#ifdef HAVE_RENAMEAT
15500 { "HAVE_RENAMEAT", probe_renameat },
15501#endif
15502
15503#ifdef HAVE_SYMLINKAT
15504 { "HAVE_SYMLINKAT", probe_symlinkat },
15505#endif
15506
15507#ifdef HAVE_UNLINKAT
15508 { "HAVE_UNLINKAT", probe_unlinkat },
15509#endif
15510
15511#ifdef HAVE_UTIMENSAT
15512 { "HAVE_UTIMENSAT", probe_utimensat },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015513#endif
15514
15515#ifdef MS_WINDOWS
Ronald Oussoren41761932020-11-08 10:05:27 +010015516 { "MS_WINDOWS", NULL },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015517#endif
15518
Ronald Oussoren41761932020-11-08 10:05:27 +010015519 { NULL, NULL }
Larry Hastings9cf065c2012-06-22 16:30:09 -070015520};
15521
15522
Victor Stinner1c2fa782020-05-10 11:05:29 +020015523static int
15524posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000015525{
Victor Stinner97f33c32020-05-14 18:05:58 +020015526 _posixstate *state = get_posix_state(m);
Tim Peters5aa91602002-01-30 05:46:57 +000015527
Ronald Oussoren41761932020-11-08 10:05:27 +010015528#if defined(HAVE_PWRITEV)
15529 if (HAVE_PWRITEV_RUNTIME) {} else {
15530 PyObject* dct = PyModule_GetDict(m);
15531
15532 if (dct == NULL) {
15533 return -1;
15534 }
15535
15536 if (PyDict_DelItemString(dct, "pwritev") == -1) {
15537 PyErr_Clear();
15538 }
15539 if (PyDict_DelItemString(dct, "preadv") == -1) {
15540 PyErr_Clear();
15541 }
15542 }
15543#endif
15544
Victor Stinner8c62be82010-05-06 00:08:46 +000015545 /* Initialize environ dictionary */
Victor Stinner97f33c32020-05-14 18:05:58 +020015546 PyObject *v = convertenviron();
Victor Stinner8c62be82010-05-06 00:08:46 +000015547 Py_XINCREF(v);
15548 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015549 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015550 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000015551
Victor Stinner8c62be82010-05-06 00:08:46 +000015552 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015553 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000015554
Victor Stinner8c62be82010-05-06 00:08:46 +000015555 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015556 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000015557
Victor Stinner8c62be82010-05-06 00:08:46 +000015558 Py_INCREF(PyExc_OSError);
15559 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000015560
Ross Lagerwall7807c352011-03-17 20:20:30 +020015561#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080015562 waitid_result_desc.name = MODNAME ".waitid_result";
15563 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
15564 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015565 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015566 }
15567 Py_INCREF(WaitidResultType);
15568 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015569 state->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015570#endif
15571
Eddie Elizondob3966632019-11-05 07:16:14 -080015572 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
15573 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
15574 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
15575 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
15576 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
15577 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015578 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015579 }
15580 Py_INCREF(StatResultType);
15581 PyModule_AddObject(m, "stat_result", StatResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015582 state->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015583 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
15584 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015585
Eddie Elizondob3966632019-11-05 07:16:14 -080015586 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
15587 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
15588 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015589 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015590 }
15591 Py_INCREF(StatVFSResultType);
15592 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015593 state->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015594#ifdef NEED_TICKS_PER_SECOND
15595# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080015596 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015597# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080015598 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015599# else
Eddie Elizondob3966632019-11-05 07:16:14 -080015600 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015601# endif
15602#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015603
William Orr81574b82018-10-01 22:19:56 -070015604#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080015605 sched_param_desc.name = MODNAME ".sched_param";
15606 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
15607 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015608 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015609 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015610 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080015611 PyModule_AddObject(m, "sched_param", SchedParamType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015612 state->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015613 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050015614#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000015615
Eddie Elizondob3966632019-11-05 07:16:14 -080015616 /* initialize TerminalSize_info */
15617 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
15618 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015619 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015620 }
15621 Py_INCREF(TerminalSizeType);
15622 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015623 state->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015624
15625 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020015626 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015627 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015628 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015629 }
Victor Stinner97f33c32020-05-14 18:05:58 +020015630 state->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015631
Victor Stinner1c2fa782020-05-10 11:05:29 +020015632 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015633 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015634 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015635 }
15636 Py_INCREF(DirEntryType);
15637 PyModule_AddObject(m, "DirEntry", DirEntryType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015638 state->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015639
Larry Hastings605a62d2012-06-24 04:33:36 -070015640 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080015641 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015642 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015643 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015644 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015645 Py_INCREF(TimesResultType);
15646 PyModule_AddObject(m, "times_result", TimesResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015647 state->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015648
Eddie Elizondob3966632019-11-05 07:16:14 -080015649 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015650 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015651 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015652 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015653 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015654 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015655 state->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015656
Victor Stinner97f33c32020-05-14 18:05:58 +020015657 if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015658 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015659#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +020015660 state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
15661 if (state->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015662 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015663#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020015664 state->st_mode = PyUnicode_InternFromString("st_mode");
15665 if (state->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015666 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070015667
Larry Hastings9cf065c2012-06-22 16:30:09 -070015668 /* suppress "function not used" warnings */
15669 {
15670 int ignored;
15671 fd_specified("", -1);
15672 follow_symlinks_specified("", 1);
15673 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
15674 dir_fd_converter(Py_None, &ignored);
15675 dir_fd_unavailable(Py_None, &ignored);
15676 }
15677
15678 /*
15679 * provide list of locally available functions
15680 * so os.py can populate support_* lists
15681 */
Victor Stinner97f33c32020-05-14 18:05:58 +020015682 PyObject *list = PyList_New(0);
15683 if (!list) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015684 return -1;
Victor Stinner97f33c32020-05-14 18:05:58 +020015685 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015686 for (const struct have_function *trace = have_functions; trace->label; trace++) {
15687 PyObject *unicode;
15688 if (trace->probe && !trace->probe()) continue;
15689 unicode = PyUnicode_DecodeASCII(trace->label, strlen(trace->label), NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015690 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015691 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015692 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015693 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015694 Py_DECREF(unicode);
15695 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015696
Larry Hastings9cf065c2012-06-22 16:30:09 -070015697 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040015698
Victor Stinner1c2fa782020-05-10 11:05:29 +020015699 return 0;
15700}
15701
15702
15703static PyModuleDef_Slot posixmodile_slots[] = {
15704 {Py_mod_exec, posixmodule_exec},
15705 {0, NULL}
15706};
15707
15708static struct PyModuleDef posixmodule = {
15709 PyModuleDef_HEAD_INIT,
15710 .m_name = MODNAME,
15711 .m_doc = posix__doc__,
15712 .m_size = sizeof(_posixstate),
15713 .m_methods = posix_methods,
15714 .m_slots = posixmodile_slots,
15715 .m_traverse = _posix_traverse,
15716 .m_clear = _posix_clear,
15717 .m_free = _posix_free,
15718};
15719
15720PyMODINIT_FUNC
15721INITFUNC(void)
15722{
15723 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015724}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015725
15726#ifdef __cplusplus
15727}
15728#endif