blob: 03de4703239a7c308e891e0593f94302e8a11c88 [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 Stinnercdad2722021-04-22 00:52:52 +020014#include "pycore_moduleobject.h" // _PyModule_GetState()
Victor Stinnerd5d9e812019-05-13 12:35:37 +020015#ifdef MS_WINDOWS
16 /* include <windows.h> early to avoid conflict with pycore_condvar.h:
17
18 #define WIN32_LEAN_AND_MEAN
19 #include <windows.h>
20
21 FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
22# include <windows.h>
Steve Dower04732ca2021-04-07 01:02:07 +010023# include <pathcch.h>
Victor Stinnerd5d9e812019-05-13 12:35:37 +020024#endif
25
pxinwr3405e052020-08-07 13:21:52 +080026#ifdef __VXWORKS__
27# include "pycore_bitutils.h" // _Py_popcount32()
28#endif
Victor Stinner4a21e572020-04-15 02:35:41 +020029#include "pycore_ceval.h" // _PyEval_ReInitThreads()
30#include "pycore_import.h" // _PyImport_ReInitLock()
Victor Stinner26881c82020-06-02 15:51:37 +020031#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
Victor Stinner4a21e572020-04-15 02:35:41 +020032#include "pycore_pystate.h" // _PyInterpreterState_GET()
33#include "structmember.h" // PyMemberDef
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020034#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020035# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010036#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020037# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020038#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020040/* On android API level 21, 'AT_EACCESS' is not declared although
41 * HAVE_FACCESSAT is defined. */
42#ifdef __ANDROID__
Victor Stinner5eca75d2020-04-15 15:07:31 +020043# undef HAVE_FACCESSAT
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020044#endif
45
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000046#include <stdio.h> /* needed for ctermid() */
47
Ronald Oussoren41761932020-11-08 10:05:27 +010048/*
49 * A number of APIs are available on macOS from a certain macOS version.
50 * To support building with a new SDK while deploying to older versions
51 * the availability test is split into two:
52 * - HAVE_<FUNCTION>: The configure check for compile time availability
53 * - HAVE_<FUNCTION>_RUNTIME: Runtime check for availability
54 *
55 * The latter is always true when not on macOS, or when using a compiler
56 * that does not support __has_builtin (older versions of Xcode).
57 *
58 * Due to compiler restrictions there is one valid use of HAVE_<FUNCTION>_RUNTIME:
59 * if (HAVE_<FUNCTION>_RUNTIME) { ... }
60 *
61 * In mixing the test with other tests or using negations will result in compile
62 * errors.
63 */
64#if defined(__APPLE__)
65
Joshua Rootdf21f502021-01-04 21:36:58 +110066#if defined(__has_builtin)
67#if __has_builtin(__builtin_available)
68#define HAVE_BUILTIN_AVAILABLE 1
69#endif
70#endif
71
72#ifdef HAVE_BUILTIN_AVAILABLE
Ronald Oussoren41761932020-11-08 10:05:27 +010073# define HAVE_FSTATAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
74# define HAVE_FACCESSAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
75# define HAVE_FCHMODAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
76# define HAVE_FCHOWNAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
77# define HAVE_LINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
78# define HAVE_FDOPENDIR_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
79# define HAVE_MKDIRAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
80# define HAVE_RENAMEAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
81# define HAVE_UNLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
82# define HAVE_OPENAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
83# define HAVE_READLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
84# define HAVE_SYMLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
85# define HAVE_FUTIMENS_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
86# define HAVE_UTIMENSAT_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
87# define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
88
89# define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *)
90
91#else /* Xcode 8 or earlier */
92
93 /* __builtin_available is not present in these compilers, but
94 * some of the symbols might be weak linked (10.10 SDK or later
95 * deploying on 10.9.
96 *
97 * Fall back to the older style of availability checking for
98 * symbols introduced in macOS 10.10.
99 */
100
101# ifdef HAVE_FSTATAT
102# define HAVE_FSTATAT_RUNTIME (fstatat != NULL)
103# endif
104
105# ifdef HAVE_FACCESSAT
106# define HAVE_FACCESSAT_RUNTIME (faccessat != NULL)
107# endif
108
109# ifdef HAVE_FCHMODAT
110# define HAVE_FCHMODAT_RUNTIME (fchmodat != NULL)
111# endif
112
113# ifdef HAVE_FCHOWNAT
114# define HAVE_FCHOWNAT_RUNTIME (fchownat != NULL)
115# endif
116
117# ifdef HAVE_LINKAT
118# define HAVE_LINKAT_RUNTIME (linkat != NULL)
119# endif
120
121# ifdef HAVE_FDOPENDIR
122# define HAVE_FDOPENDIR_RUNTIME (fdopendir != NULL)
123# endif
124
125# ifdef HAVE_MKDIRAT
126# define HAVE_MKDIRAT_RUNTIME (mkdirat != NULL)
127# endif
128
129# ifdef HAVE_RENAMEAT
130# define HAVE_RENAMEAT_RUNTIME (renameat != NULL)
131# endif
132
133# ifdef HAVE_UNLINKAT
134# define HAVE_UNLINKAT_RUNTIME (unlinkat != NULL)
135# endif
136
137# ifdef HAVE_OPENAT
138# define HAVE_OPENAT_RUNTIME (openat != NULL)
139# endif
140
141# ifdef HAVE_READLINKAT
142# define HAVE_READLINKAT_RUNTIME (readlinkat != NULL)
143# endif
144
145# ifdef HAVE_SYMLINKAT
146# define HAVE_SYMLINKAT_RUNTIME (symlinkat != NULL)
147# endif
148
149#endif
150
151#ifdef HAVE_FUTIMESAT
152/* Some of the logic for weak linking depends on this assertion */
153# error "HAVE_FUTIMESAT unexpectedly defined"
154#endif
155
156#else
157# define HAVE_FSTATAT_RUNTIME 1
158# define HAVE_FACCESSAT_RUNTIME 1
159# define HAVE_FCHMODAT_RUNTIME 1
160# define HAVE_FCHOWNAT_RUNTIME 1
161# define HAVE_LINKAT_RUNTIME 1
162# define HAVE_FDOPENDIR_RUNTIME 1
163# define HAVE_MKDIRAT_RUNTIME 1
164# define HAVE_RENAMEAT_RUNTIME 1
165# define HAVE_UNLINKAT_RUNTIME 1
166# define HAVE_OPENAT_RUNTIME 1
167# define HAVE_READLINKAT_RUNTIME 1
168# define HAVE_SYMLINKAT_RUNTIME 1
169# define HAVE_FUTIMENS_RUNTIME 1
170# define HAVE_UTIMENSAT_RUNTIME 1
171# define HAVE_PWRITEV_RUNTIME 1
172#endif
173
174
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000175#ifdef __cplusplus
176extern "C" {
177#endif
178
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000179PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000180"This module provides access to operating system functionality that is\n\
181standardized by the C Standard and the POSIX standard (a thinly\n\
182disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000183corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184
Martin v. Löwis0073f2e2002-11-21 23:52:35 +0000185
Ross Lagerwall4d076da2011-03-18 06:56:53 +0200186#ifdef HAVE_SYS_UIO_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200187# include <sys/uio.h>
Ross Lagerwall4d076da2011-03-18 06:56:53 +0200188#endif
189
Christian Heimes75b96182017-09-05 15:53:09 +0200190#ifdef HAVE_SYS_SYSMACROS_H
191/* GNU C Library: major(), minor(), makedev() */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200192# include <sys/sysmacros.h>
Christian Heimes75b96182017-09-05 15:53:09 +0200193#endif
194
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000195#ifdef HAVE_SYS_TYPES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200196# include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000197#endif /* HAVE_SYS_TYPES_H */
198
199#ifdef HAVE_SYS_STAT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200200# include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000201#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000202
Guido van Rossum36bc6801995-06-14 22:54:23 +0000203#ifdef HAVE_SYS_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200204# include <sys/wait.h> // WNOHANG
Guido van Rossum36bc6801995-06-14 22:54:23 +0000205#endif
Benjamin Peterson5c0c3252019-11-05 21:58:31 -0800206#ifdef HAVE_LINUX_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200207# include <linux/wait.h> // P_PIDFD
Benjamin Peterson5c0c3252019-11-05 21:58:31 -0800208#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000210#ifdef HAVE_SIGNAL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200211# include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000212#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +0000213
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#ifdef HAVE_FCNTL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200215# include <fcntl.h>
216#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000218#ifdef HAVE_GRP_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200219# include <grp.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000220#endif
221
Barry Warsaw5676bd12003-01-07 20:57:09 +0000222#ifdef HAVE_SYSEXITS_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200223# include <sysexits.h>
224#endif
Barry Warsaw5676bd12003-01-07 20:57:09 +0000225
Anthony Baxter8a560de2004-10-13 15:30:56 +0000226#ifdef HAVE_SYS_LOADAVG_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200227# include <sys/loadavg.h>
Anthony Baxter8a560de2004-10-13 15:30:56 +0000228#endif
229
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000230#ifdef HAVE_SYS_SENDFILE_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200231# include <sys/sendfile.h>
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000232#endif
233
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200234#if defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200235# include <copyfile.h>
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200236#endif
237
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500238#ifdef HAVE_SCHED_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200239# include <sched.h>
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500240#endif
241
Pablo Galindoaac4d032019-05-31 19:39:47 +0100242#ifdef HAVE_COPY_FILE_RANGE
Victor Stinner5eca75d2020-04-15 15:07:31 +0200243# include <unistd.h>
Pablo Galindoaac4d032019-05-31 19:39:47 +0100244#endif
245
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500246#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200247# undef HAVE_SCHED_SETAFFINITY
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500248#endif
249
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200250#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200251# define USE_XATTRS
Benjamin Peterson9428d532011-09-14 11:45:52 -0400252#endif
253
254#ifdef USE_XATTRS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200255# include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400256#endif
257
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000258#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200259# ifdef HAVE_SYS_SOCKET_H
260# include <sys/socket.h>
261# endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000262#endif
263
Victor Stinner8b905bd2011-10-25 13:34:04 +0200264#ifdef HAVE_DLFCN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200265# include <dlfcn.h>
Victor Stinner8b905bd2011-10-25 13:34:04 +0200266#endif
267
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200268#ifdef __hpux
Victor Stinner5eca75d2020-04-15 15:07:31 +0200269# include <sys/mpctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200270#endif
271
272#if defined(__DragonFly__) || \
273 defined(__OpenBSD__) || \
274 defined(__FreeBSD__) || \
275 defined(__NetBSD__) || \
276 defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200277# include <sys/sysctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200278#endif
279
Victor Stinner9b1f4742016-09-06 16:18:52 -0700280#ifdef HAVE_LINUX_RANDOM_H
281# include <linux/random.h>
282#endif
283#ifdef HAVE_GETRANDOM_SYSCALL
284# include <sys/syscall.h>
285#endif
286
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100287#if defined(MS_WINDOWS)
288# define TERMSIZE_USE_CONIO
289#elif defined(HAVE_SYS_IOCTL_H)
290# include <sys/ioctl.h>
291# if defined(HAVE_TERMIOS_H)
292# include <termios.h>
293# endif
294# if defined(TIOCGWINSZ)
295# define TERMSIZE_USE_IOCTL
296# endif
297#endif /* MS_WINDOWS */
298
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000299/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000300/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000301#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200302# define HAVE_OPENDIR 1
303# define HAVE_SYSTEM 1
304# include <process.h>
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000305#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200306# ifdef _MSC_VER
307 /* Microsoft compiler */
308# define HAVE_GETPPID 1
309# define HAVE_GETLOGIN 1
310# define HAVE_SPAWNV 1
311# define HAVE_EXECV 1
312# define HAVE_WSPAWNV 1
313# define HAVE_WEXECV 1
314# define HAVE_PIPE 1
315# define HAVE_SYSTEM 1
316# define HAVE_CWAIT 1
317# define HAVE_FSYNC 1
318# define fsync _commit
319# else
320 /* Unix functions that the configure script doesn't check for */
321# ifndef __VXWORKS__
322# define HAVE_EXECV 1
323# define HAVE_FORK 1
324# if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
325# define HAVE_FORK1 1
326# endif
327# endif
328# define HAVE_GETEGID 1
329# define HAVE_GETEUID 1
330# define HAVE_GETGID 1
331# define HAVE_GETPPID 1
332# define HAVE_GETUID 1
333# define HAVE_KILL 1
334# define HAVE_OPENDIR 1
335# define HAVE_PIPE 1
336# define HAVE_SYSTEM 1
337# define HAVE_WAIT 1
338# define HAVE_TTYNAME 1
339# endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000340#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000341
Eddie Elizondob3966632019-11-05 07:16:14 -0800342_Py_IDENTIFIER(__fspath__);
Victor Stinnera2f7c002012-02-08 03:36:25 +0100343
Larry Hastings61272b72014-01-07 12:41:53 -0800344/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000345# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800346module os
Larry Hastings61272b72014-01-07 12:41:53 -0800347[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000348/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100349
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000350#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000351
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000352#if defined(__sgi)&&_COMPILER_VERSION>=700
353/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
354 (default) */
355extern char *ctermid_r(char *);
356#endif
357
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000358#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000359
pxinwrf2d7ac72019-05-21 18:46:37 +0800360#if defined(__VXWORKS__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200361# include <vxCpuLib.h>
362# include <rtpLib.h>
363# include <wait.h>
364# include <taskLib.h>
365# ifndef _P_WAIT
366# define _P_WAIT 0
367# define _P_NOWAIT 1
368# define _P_NOWAITO 1
369# endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800370#endif /* __VXWORKS__ */
371
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000372#ifdef HAVE_POSIX_SPAWN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200373# include <spawn.h>
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000374#endif
375
Guido van Rossumb6775db1994-08-01 11:34:53 +0000376#ifdef HAVE_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200377# include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000378#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000379
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000380#ifdef HAVE_SYS_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200381# include <sys/utime.h>
382# define HAVE_UTIME_H /* pretend we do for the rest of this file */
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000383#endif /* HAVE_SYS_UTIME_H */
384
Guido van Rossumb6775db1994-08-01 11:34:53 +0000385#ifdef HAVE_SYS_TIMES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200386# include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000387#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000388
389#ifdef HAVE_SYS_PARAM_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200390# include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000391#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000392
393#ifdef HAVE_SYS_UTSNAME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200394# include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000395#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000396
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000397#ifdef HAVE_DIRENT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200398# include <dirent.h>
399# define NAMLEN(dirent) strlen((dirent)->d_name)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000400#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200401# if defined(__WATCOMC__) && !defined(__QNX__)
402# include <direct.h>
403# define NAMLEN(dirent) strlen((dirent)->d_name)
404# else
405# define dirent direct
406# define NAMLEN(dirent) (dirent)->d_namlen
407# endif
408# ifdef HAVE_SYS_NDIR_H
409# include <sys/ndir.h>
410# endif
411# ifdef HAVE_SYS_DIR_H
412# include <sys/dir.h>
413# endif
414# ifdef HAVE_NDIR_H
415# include <ndir.h>
416# endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000417#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000418
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000419#ifdef _MSC_VER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200420# ifdef HAVE_DIRECT_H
421# include <direct.h>
422# endif
423# ifdef HAVE_IO_H
424# include <io.h>
425# endif
426# ifdef HAVE_PROCESS_H
427# include <process.h>
428# endif
429# ifndef IO_REPARSE_TAG_SYMLINK
430# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
431# endif
432# ifndef IO_REPARSE_TAG_MOUNT_POINT
433# define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
434# endif
435# include "osdefs.h" // SEP
436# include <malloc.h>
437# include <windows.h>
438# include <shellapi.h> // ShellExecute()
439# include <lmcons.h> // UNLEN
440# define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000441#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000442
Tim Petersbc2e10e2002-03-03 23:17:02 +0000443#ifndef MAXPATHLEN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200444# if defined(PATH_MAX) && PATH_MAX > 1024
445# define MAXPATHLEN PATH_MAX
446# else
447# define MAXPATHLEN 1024
448# endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000449#endif /* MAXPATHLEN */
450
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000451#ifdef UNION_WAIT
Victor Stinner5eca75d2020-04-15 15:07:31 +0200452 /* Emulate some macros on systems that have a union instead of macros */
453# ifndef WIFEXITED
454# define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
455# endif
456# ifndef WEXITSTATUS
457# define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
458# endif
459# ifndef WTERMSIG
460# define WTERMSIG(u_wait) ((u_wait).w_termsig)
461# endif
462# define WAIT_TYPE union wait
463# define WAIT_STATUS_INT(s) (s.w_status)
464#else
465 /* !UNION_WAIT */
466# define WAIT_TYPE int
467# define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000468#endif /* UNION_WAIT */
469
Greg Wardb48bc172000-03-01 21:51:56 +0000470/* Don't use the "_r" form if we don't need it (also, won't have a
471 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200472#if defined(HAVE_CTERMID_R)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200473# define USE_CTERMID_R
Greg Wardb48bc172000-03-01 21:51:56 +0000474#endif
475
Fred Drake699f3522000-06-29 21:12:41 +0000476/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000477#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000478#undef FSTAT
479#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200480#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200481# define STAT win32_stat
482# define LSTAT win32_lstat
483# define FSTAT _Py_fstat_noraise
484# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000485#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200486# define STAT stat
487# define LSTAT lstat
488# define FSTAT fstat
489# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000490#endif
491
Tim Peters11b23062003-04-23 02:39:17 +0000492#if defined(MAJOR_IN_MKDEV)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200493# include <sys/mkdev.h>
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000494#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200495# if defined(MAJOR_IN_SYSMACROS)
496# include <sys/sysmacros.h>
497# endif
498# if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
499# include <sys/mkdev.h>
500# endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000501#endif
Fred Drake699f3522000-06-29 21:12:41 +0000502
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200503#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200504# define INITFUNC PyInit_nt
505# define MODNAME "nt"
Victor Stinner6036e442015-03-08 01:58:04 +0100506#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200507# define INITFUNC PyInit_posix
508# define MODNAME "posix"
Victor Stinner6036e442015-03-08 01:58:04 +0100509#endif
510
jcea6c51d512018-01-28 14:00:08 +0100511#if defined(__sun)
512/* Something to implement in autoconf, not present in autoconf 2.69 */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200513# define HAVE_STRUCT_STAT_ST_FSTYPE 1
jcea6c51d512018-01-28 14:00:08 +0100514#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200515
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600516/* memfd_create is either defined in sys/mman.h or sys/memfd.h
517 * linux/memfd.h defines additional flags
518 */
519#ifdef HAVE_SYS_MMAN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200520# include <sys/mman.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600521#endif
522#ifdef HAVE_SYS_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200523# include <sys/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600524#endif
525#ifdef HAVE_LINUX_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200526# include <linux/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600527#endif
528
Christian Heimescd9fed62020-11-13 19:48:52 +0100529/* eventfd() */
530#ifdef HAVE_SYS_EVENTFD_H
531# include <sys/eventfd.h>
532#endif
533
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800534#ifdef _Py_MEMORY_SANITIZER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200535# include <sanitizer/msan_interface.h>
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800536#endif
537
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200538#ifdef HAVE_FORK
539static void
540run_at_forkers(PyObject *lst, int reverse)
541{
542 Py_ssize_t i;
543 PyObject *cpy;
544
545 if (lst != NULL) {
546 assert(PyList_CheckExact(lst));
547
548 /* Use a list copy in case register_at_fork() is called from
549 * one of the callbacks.
550 */
551 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
552 if (cpy == NULL)
553 PyErr_WriteUnraisable(lst);
554 else {
555 if (reverse)
556 PyList_Reverse(cpy);
557 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
558 PyObject *func, *res;
559 func = PyList_GET_ITEM(cpy, i);
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +0200560 res = _PyObject_CallNoArg(func);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200561 if (res == NULL)
562 PyErr_WriteUnraisable(func);
563 else
564 Py_DECREF(res);
565 }
566 Py_DECREF(cpy);
567 }
568 }
569}
570
571void
572PyOS_BeforeFork(void)
573{
Victor Stinner81a7be32020-04-14 15:14:01 +0200574 run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200575
576 _PyImport_AcquireLock();
577}
578
579void
580PyOS_AfterFork_Parent(void)
581{
582 if (_PyImport_ReleaseLock() <= 0)
583 Py_FatalError("failed releasing import lock after fork");
584
Victor Stinner81a7be32020-04-14 15:14:01 +0200585 run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200586}
587
588void
589PyOS_AfterFork_Child(void)
590{
Victor Stinner26881c82020-06-02 15:51:37 +0200591 PyStatus status;
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200592 _PyRuntimeState *runtime = &_PyRuntime;
Victor Stinner26881c82020-06-02 15:51:37 +0200593
594 status = _PyGILState_Reinit(runtime);
595 if (_PyStatus_EXCEPTION(status)) {
596 goto fatal_error;
597 }
598
Victor Stinner317bab02020-06-02 18:44:54 +0200599 PyThreadState *tstate = _PyThreadState_GET();
600 _Py_EnsureTstateNotNULL(tstate);
601
602 status = _PyEval_ReInitThreads(tstate);
Victor Stinner26881c82020-06-02 15:51:37 +0200603 if (_PyStatus_EXCEPTION(status)) {
604 goto fatal_error;
605 }
606
607 status = _PyImport_ReInitLock();
608 if (_PyStatus_EXCEPTION(status)) {
609 goto fatal_error;
610 }
611
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200612 _PySignal_AfterFork();
Victor Stinner26881c82020-06-02 15:51:37 +0200613
614 status = _PyRuntimeState_ReInitThreads(runtime);
615 if (_PyStatus_EXCEPTION(status)) {
616 goto fatal_error;
617 }
618
619 status = _PyInterpreterState_DeleteExceptMain(runtime);
620 if (_PyStatus_EXCEPTION(status)) {
621 goto fatal_error;
622 }
Victor Stinner317bab02020-06-02 18:44:54 +0200623 assert(_PyThreadState_GET() == tstate);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200624
Victor Stinner317bab02020-06-02 18:44:54 +0200625 run_at_forkers(tstate->interp->after_forkers_child, 0);
Victor Stinner26881c82020-06-02 15:51:37 +0200626 return;
627
628fatal_error:
629 Py_ExitStatusException(status);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200630}
631
632static int
633register_at_forker(PyObject **lst, PyObject *func)
634{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700635 if (func == NULL) /* nothing to register? do nothing. */
636 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200637 if (*lst == NULL) {
638 *lst = PyList_New(0);
639 if (*lst == NULL)
640 return -1;
641 }
642 return PyList_Append(*lst, func);
643}
Victor Stinner87255be2020-04-07 23:11:49 +0200644#endif /* HAVE_FORK */
645
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200646
647/* Legacy wrapper */
648void
649PyOS_AfterFork(void)
650{
651#ifdef HAVE_FORK
652 PyOS_AfterFork_Child();
653#endif
654}
655
656
Victor Stinner6036e442015-03-08 01:58:04 +0100657#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200658/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700659void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
660void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200661 ULONG, struct _Py_stat_struct *);
662#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700663
Larry Hastings9cf065c2012-06-22 16:30:09 -0700664
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200665#ifndef MS_WINDOWS
666PyObject *
667_PyLong_FromUid(uid_t uid)
668{
669 if (uid == (uid_t)-1)
670 return PyLong_FromLong(-1);
671 return PyLong_FromUnsignedLong(uid);
672}
673
674PyObject *
675_PyLong_FromGid(gid_t gid)
676{
677 if (gid == (gid_t)-1)
678 return PyLong_FromLong(-1);
679 return PyLong_FromUnsignedLong(gid);
680}
681
682int
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100683_Py_Uid_Converter(PyObject *obj, uid_t *p)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200684{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700685 uid_t uid;
686 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200687 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200688 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700689 unsigned long uresult;
690
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300691 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700692 if (index == NULL) {
693 PyErr_Format(PyExc_TypeError,
694 "uid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800695 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200696 return 0;
697 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700698
699 /*
700 * Handling uid_t is complicated for two reasons:
701 * * Although uid_t is (always?) unsigned, it still
702 * accepts -1.
703 * * We don't know its size in advance--it may be
704 * bigger than an int, or it may be smaller than
705 * a long.
706 *
707 * So a bit of defensive programming is in order.
708 * Start with interpreting the value passed
709 * in as a signed long and see if it works.
710 */
711
712 result = PyLong_AsLongAndOverflow(index, &overflow);
713
714 if (!overflow) {
715 uid = (uid_t)result;
716
717 if (result == -1) {
718 if (PyErr_Occurred())
719 goto fail;
720 /* It's a legitimate -1, we're done. */
721 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200722 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700723
724 /* Any other negative number is disallowed. */
725 if (result < 0)
726 goto underflow;
727
728 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200729 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700730 (long)uid != result)
731 goto underflow;
732 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200733 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700734
735 if (overflow < 0)
736 goto underflow;
737
738 /*
739 * Okay, the value overflowed a signed long. If it
740 * fits in an *unsigned* long, it may still be okay,
741 * as uid_t may be unsigned long on this platform.
742 */
743 uresult = PyLong_AsUnsignedLong(index);
744 if (PyErr_Occurred()) {
745 if (PyErr_ExceptionMatches(PyExc_OverflowError))
746 goto overflow;
747 goto fail;
748 }
749
750 uid = (uid_t)uresult;
751
752 /*
753 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
754 * but this value would get interpreted as (uid_t)-1 by chown
755 * and its siblings. That's not what the user meant! So we
756 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100757 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700758 */
759 if (uid == (uid_t)-1)
760 goto overflow;
761
762 /* Ensure the value wasn't truncated. */
763 if (sizeof(uid_t) < sizeof(long) &&
764 (unsigned long)uid != uresult)
765 goto overflow;
766 /* fallthrough */
767
768success:
769 Py_DECREF(index);
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100770 *p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200771 return 1;
772
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700773underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200774 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700775 "uid is less than minimum");
776 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200777
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700778overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200779 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700780 "uid is greater than maximum");
781 /* fallthrough */
782
783fail:
784 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200785 return 0;
786}
787
788int
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100789_Py_Gid_Converter(PyObject *obj, gid_t *p)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200790{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700791 gid_t gid;
792 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200793 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200794 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700795 unsigned long uresult;
796
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300797 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700798 if (index == NULL) {
799 PyErr_Format(PyExc_TypeError,
800 "gid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800801 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200802 return 0;
803 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700804
805 /*
806 * Handling gid_t is complicated for two reasons:
807 * * Although gid_t is (always?) unsigned, it still
808 * accepts -1.
809 * * We don't know its size in advance--it may be
810 * bigger than an int, or it may be smaller than
811 * a long.
812 *
813 * So a bit of defensive programming is in order.
814 * Start with interpreting the value passed
815 * in as a signed long and see if it works.
816 */
817
818 result = PyLong_AsLongAndOverflow(index, &overflow);
819
820 if (!overflow) {
821 gid = (gid_t)result;
822
823 if (result == -1) {
824 if (PyErr_Occurred())
825 goto fail;
826 /* It's a legitimate -1, we're done. */
827 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200828 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700829
830 /* Any other negative number is disallowed. */
831 if (result < 0) {
832 goto underflow;
833 }
834
835 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200836 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700837 (long)gid != result)
838 goto underflow;
839 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200840 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700841
842 if (overflow < 0)
843 goto underflow;
844
845 /*
846 * Okay, the value overflowed a signed long. If it
847 * fits in an *unsigned* long, it may still be okay,
848 * as gid_t may be unsigned long on this platform.
849 */
850 uresult = PyLong_AsUnsignedLong(index);
851 if (PyErr_Occurred()) {
852 if (PyErr_ExceptionMatches(PyExc_OverflowError))
853 goto overflow;
854 goto fail;
855 }
856
857 gid = (gid_t)uresult;
858
859 /*
860 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
861 * but this value would get interpreted as (gid_t)-1 by chown
862 * and its siblings. That's not what the user meant! So we
863 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100864 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700865 */
866 if (gid == (gid_t)-1)
867 goto overflow;
868
869 /* Ensure the value wasn't truncated. */
870 if (sizeof(gid_t) < sizeof(long) &&
871 (unsigned long)gid != uresult)
872 goto overflow;
873 /* fallthrough */
874
875success:
876 Py_DECREF(index);
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100877 *p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200878 return 1;
879
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700880underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200881 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700882 "gid is less than minimum");
883 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200884
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700885overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200886 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700887 "gid is greater than maximum");
888 /* fallthrough */
889
890fail:
891 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200892 return 0;
893}
894#endif /* MS_WINDOWS */
895
896
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700897#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800898
899
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200900#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
901static int
902_Py_Dev_Converter(PyObject *obj, void *p)
903{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200904 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200905 if (PyErr_Occurred())
906 return 0;
907 return 1;
908}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800909#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200910
911
Larry Hastings9cf065c2012-06-22 16:30:09 -0700912#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400913/*
914 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
915 * without the int cast, the value gets interpreted as uint (4291925331),
916 * which doesn't play nicely with all the initializer lines in this file that
917 * look like this:
918 * int dir_fd = DEFAULT_DIR_FD;
919 */
920#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700921#else
922#define DEFAULT_DIR_FD (-100)
923#endif
924
925static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300926_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200927{
928 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700929 long long_value;
930
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300931 PyObject *index = _PyNumber_Index(o);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700932 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933 return 0;
934 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700935
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300936 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700937 long_value = PyLong_AsLongAndOverflow(index, &overflow);
938 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300939 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200940 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700942 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943 return 0;
944 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200945 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700946 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700947 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700948 return 0;
949 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700950
Larry Hastings9cf065c2012-06-22 16:30:09 -0700951 *p = (int)long_value;
952 return 1;
953}
954
955static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200956dir_fd_converter(PyObject *o, void *p)
957{
958 if (o == Py_None) {
959 *(int *)p = DEFAULT_DIR_FD;
960 return 1;
961 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300962 else if (PyIndex_Check(o)) {
963 return _fd_converter(o, (int *)p);
964 }
965 else {
966 PyErr_Format(PyExc_TypeError,
967 "argument should be integer or None, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800968 _PyType_Name(Py_TYPE(o)));
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300969 return 0;
970 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700971}
972
Eddie Elizondob3966632019-11-05 07:16:14 -0800973typedef struct {
974 PyObject *billion;
Eddie Elizondob3966632019-11-05 07:16:14 -0800975 PyObject *DirEntryType;
976 PyObject *ScandirIteratorType;
977#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
978 PyObject *SchedParamType;
979#endif
980 PyObject *StatResultType;
981 PyObject *StatVFSResultType;
982 PyObject *TerminalSizeType;
983 PyObject *TimesResultType;
984 PyObject *UnameResultType;
985#if defined(HAVE_WAITID) && !defined(__APPLE__)
986 PyObject *WaitidResultType;
987#endif
988#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
989 PyObject *struct_rusage;
990#endif
991 PyObject *st_mode;
992} _posixstate;
993
Eddie Elizondob3966632019-11-05 07:16:14 -0800994
Hai Shif707d942020-03-16 21:15:01 +0800995static inline _posixstate*
996get_posix_state(PyObject *module)
997{
Victor Stinnercdad2722021-04-22 00:52:52 +0200998 void *state = _PyModule_GetState(module);
Hai Shif707d942020-03-16 21:15:01 +0800999 assert(state != NULL);
1000 return (_posixstate *)state;
1001}
1002
Larry Hastings9cf065c2012-06-22 16:30:09 -07001003/*
1004 * A PyArg_ParseTuple "converter" function
1005 * that handles filesystem paths in the manner
1006 * preferred by the os module.
1007 *
1008 * path_converter accepts (Unicode) strings and their
1009 * subclasses, and bytes and their subclasses. What
1010 * it does with the argument depends on the platform:
1011 *
1012 * * On Windows, if we get a (Unicode) string we
1013 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -07001014 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -07001015 *
1016 * * On all other platforms, strings are encoded
1017 * to bytes using PyUnicode_FSConverter, then we
1018 * extract the char * from the bytes object and
1019 * return that.
1020 *
1021 * path_converter also optionally accepts signed
1022 * integers (representing open file descriptors) instead
1023 * of path strings.
1024 *
1025 * Input fields:
1026 * path.nullable
1027 * If nonzero, the path is permitted to be None.
1028 * path.allow_fd
1029 * If nonzero, the path is permitted to be a file handle
1030 * (a signed int) instead of a string.
1031 * path.function_name
1032 * If non-NULL, path_converter will use that as the name
1033 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -07001034 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001035 * path.argument_name
1036 * If non-NULL, path_converter will use that as the name
1037 * of the parameter in error messages.
1038 * (If path.argument_name is NULL it uses "path".)
1039 *
1040 * Output fields:
1041 * path.wide
1042 * Points to the path if it was expressed as Unicode
1043 * and was not encoded. (Only used on Windows.)
1044 * path.narrow
1045 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -07001046 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +00001047 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -07001048 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001049 * path.fd
1050 * Contains a file descriptor if path.accept_fd was true
1051 * and the caller provided a signed integer instead of any
1052 * sort of string.
1053 *
1054 * WARNING: if your "path" parameter is optional, and is
1055 * unspecified, path_converter will never get called.
1056 * So if you set allow_fd, you *MUST* initialize path.fd = -1
1057 * yourself!
1058 * path.length
1059 * The length of the path in characters, if specified as
1060 * a string.
1061 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +08001062 * The original object passed in (if get a PathLike object,
1063 * the result of PyOS_FSPath() is treated as the original object).
1064 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -07001065 * path.cleanup
1066 * For internal use only. May point to a temporary object.
1067 * (Pay no attention to the man behind the curtain.)
1068 *
1069 * At most one of path.wide or path.narrow will be non-NULL.
1070 * If path was None and path.nullable was set,
1071 * or if path was an integer and path.allow_fd was set,
1072 * both path.wide and path.narrow will be NULL
1073 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +02001074 *
Larry Hastings9cf065c2012-06-22 16:30:09 -07001075 * path_converter takes care to not write to the path_t
1076 * unless it's successful. However it must reset the
1077 * "cleanup" field each time it's called.
1078 *
1079 * Use as follows:
1080 * path_t path;
1081 * memset(&path, 0, sizeof(path));
1082 * PyArg_ParseTuple(args, "O&", path_converter, &path);
1083 * // ... use values from path ...
1084 * path_cleanup(&path);
1085 *
1086 * (Note that if PyArg_Parse fails you don't need to call
1087 * path_cleanup(). However it is safe to do so.)
1088 */
1089typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +01001090 const char *function_name;
1091 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001092 int nullable;
1093 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001094 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -07001095#ifdef MS_WINDOWS
1096 BOOL narrow;
1097#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001098 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001099#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001100 int fd;
1101 Py_ssize_t length;
1102 PyObject *object;
1103 PyObject *cleanup;
1104} path_t;
1105
Steve Dowercc16be82016-09-08 10:35:16 -07001106#ifdef MS_WINDOWS
1107#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1108 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
1109#else
Larry Hastings2f936352014-08-05 14:04:04 +10001110#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1111 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -07001112#endif
Larry Hastings31826802013-10-19 00:09:25 -07001113
Larry Hastings9cf065c2012-06-22 16:30:09 -07001114static void
Xiang Zhang04316c42017-01-08 23:26:57 +08001115path_cleanup(path_t *path)
1116{
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001117#if !USE_UNICODE_WCHAR_CACHE
1118 wchar_t *wide = (wchar_t *)path->wide;
1119 path->wide = NULL;
1120 PyMem_Free(wide);
1121#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001122 Py_CLEAR(path->object);
1123 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001124}
1125
1126static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001127path_converter(PyObject *o, void *p)
1128{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001129 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +08001130 PyObject *bytes = NULL;
1131 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001132 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001133 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001134#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +08001135 PyObject *wo = NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001136 wchar_t *wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001137#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001138
1139#define FORMAT_EXCEPTION(exc, fmt) \
1140 PyErr_Format(exc, "%s%s" fmt, \
1141 path->function_name ? path->function_name : "", \
1142 path->function_name ? ": " : "", \
1143 path->argument_name ? path->argument_name : "path")
1144
1145 /* Py_CLEANUP_SUPPORTED support */
1146 if (o == NULL) {
1147 path_cleanup(path);
1148 return 1;
1149 }
1150
Brett Cannon3f9183b2016-08-26 14:44:48 -07001151 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +08001152 path->object = path->cleanup = NULL;
1153 /* path->object owns a reference to the original object */
1154 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001155
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001156 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001157 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001158#ifdef MS_WINDOWS
1159 path->narrow = FALSE;
1160#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001161 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001162#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001163 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001164 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001165 }
1166
Brett Cannon3f9183b2016-08-26 14:44:48 -07001167 /* Only call this here so that we don't treat the return value of
1168 os.fspath() as an fd or buffer. */
1169 is_index = path->allow_fd && PyIndex_Check(o);
1170 is_buffer = PyObject_CheckBuffer(o);
1171 is_bytes = PyBytes_Check(o);
1172 is_unicode = PyUnicode_Check(o);
1173
1174 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
1175 /* Inline PyOS_FSPath() for better error messages. */
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001176 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001177
1178 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1179 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001180 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001181 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001182 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001183 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001184 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001185 goto error_exit;
1186 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001187 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001188 is_unicode = 1;
1189 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001190 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001191 is_bytes = 1;
1192 }
1193 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001194 PyErr_Format(PyExc_TypeError,
1195 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -08001196 "not %.200s", _PyType_Name(Py_TYPE(o)),
1197 _PyType_Name(Py_TYPE(res)));
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001198 Py_DECREF(res);
1199 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001200 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001201
1202 /* still owns a reference to the original object */
1203 Py_DECREF(o);
1204 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001205 }
1206
1207 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001208#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001209#if USE_UNICODE_WCHAR_CACHE
1210_Py_COMP_DIAG_PUSH
1211_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001212 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001213_Py_COMP_DIAG_POP
1214#else /* USE_UNICODE_WCHAR_CACHE */
1215 wide = PyUnicode_AsWideCharString(o, &length);
1216#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner59799a82013-11-13 14:17:30 +01001217 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001218 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 }
Victor Stinner59799a82013-11-13 14:17:30 +01001220 if (length > 32767) {
1221 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001222 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001223 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001224 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001225 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001226 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001227 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001228
1229 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001230 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001231 path->fd = -1;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001232#if !USE_UNICODE_WCHAR_CACHE
1233 wide = NULL;
1234#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001235 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001236#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001237 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001238 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001239 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001240#endif
1241 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001242 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001243 bytes = o;
1244 Py_INCREF(bytes);
1245 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001246 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001247 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001248 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001249 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1250 "%s%s%s should be %s, not %.200s",
1251 path->function_name ? path->function_name : "",
1252 path->function_name ? ": " : "",
1253 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001254 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1255 "integer or None" :
1256 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1257 path->nullable ? "string, bytes, os.PathLike or None" :
1258 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001259 _PyType_Name(Py_TYPE(o)))) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001260 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001261 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001262 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001263 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001264 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001265 }
1266 }
Steve Dowercc16be82016-09-08 10:35:16 -07001267 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001268 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001269 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001270 }
1271 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001272#ifdef MS_WINDOWS
1273 path->narrow = FALSE;
1274#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001275 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001276#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001277 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001278 }
1279 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001280 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001281 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1282 path->function_name ? path->function_name : "",
1283 path->function_name ? ": " : "",
1284 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001285 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1286 "integer or None" :
1287 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1288 path->nullable ? "string, bytes, os.PathLike or None" :
1289 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001290 _PyType_Name(Py_TYPE(o)));
Xiang Zhang04316c42017-01-08 23:26:57 +08001291 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001292 }
1293
Larry Hastings9cf065c2012-06-22 16:30:09 -07001294 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001295 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001296 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001297 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001298 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001299 }
1300
Steve Dowercc16be82016-09-08 10:35:16 -07001301#ifdef MS_WINDOWS
1302 wo = PyUnicode_DecodeFSDefaultAndSize(
1303 narrow,
1304 length
1305 );
1306 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001307 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001308 }
1309
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001310#if USE_UNICODE_WCHAR_CACHE
1311_Py_COMP_DIAG_PUSH
1312_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Xiang Zhang04316c42017-01-08 23:26:57 +08001313 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001314_Py_COMP_DIAG_POP
1315#else /* USE_UNICODE_WCHAR_CACHE */
1316 wide = PyUnicode_AsWideCharString(wo, &length);
1317 Py_DECREF(wo);
1318#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001319 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001320 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001321 }
1322 if (length > 32767) {
1323 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001324 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001325 }
1326 if (wcslen(wide) != length) {
1327 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001328 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001329 }
1330 path->wide = wide;
1331 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001332 Py_DECREF(bytes);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001333#if USE_UNICODE_WCHAR_CACHE
1334 path->cleanup = wo;
1335#else /* USE_UNICODE_WCHAR_CACHE */
1336 wide = NULL;
1337#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001338#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001339 path->wide = NULL;
1340 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001341 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001342 /* Still a reference owned by path->object, don't have to
1343 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001344 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001345 }
1346 else {
1347 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001348 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001349#endif
1350 path->fd = -1;
1351
1352 success_exit:
1353 path->length = length;
1354 path->object = o;
1355 return Py_CLEANUP_SUPPORTED;
1356
1357 error_exit:
1358 Py_XDECREF(o);
1359 Py_XDECREF(bytes);
1360#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001361#if USE_UNICODE_WCHAR_CACHE
Xiang Zhang04316c42017-01-08 23:26:57 +08001362 Py_XDECREF(wo);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001363#else /* USE_UNICODE_WCHAR_CACHE */
1364 PyMem_Free(wide);
1365#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001366#endif
1367 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001368}
1369
1370static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001371argument_unavailable_error(const char *function_name, const char *argument_name)
1372{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001373 PyErr_Format(PyExc_NotImplementedError,
1374 "%s%s%s unavailable on this platform",
1375 (function_name != NULL) ? function_name : "",
1376 (function_name != NULL) ? ": ": "",
1377 argument_name);
1378}
1379
1380static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001381dir_fd_unavailable(PyObject *o, void *p)
1382{
1383 int dir_fd;
1384 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001385 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001386 if (dir_fd != DEFAULT_DIR_FD) {
1387 argument_unavailable_error(NULL, "dir_fd");
1388 return 0;
1389 }
1390 *(int *)p = dir_fd;
1391 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001392}
1393
1394static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001395fd_specified(const char *function_name, int fd)
1396{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001397 if (fd == -1)
1398 return 0;
1399
1400 argument_unavailable_error(function_name, "fd");
1401 return 1;
1402}
1403
1404static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001405follow_symlinks_specified(const char *function_name, int follow_symlinks)
1406{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001407 if (follow_symlinks)
1408 return 0;
1409
1410 argument_unavailable_error(function_name, "follow_symlinks");
1411 return 1;
1412}
1413
1414static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001415path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1416{
Steve Dowercc16be82016-09-08 10:35:16 -07001417 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1418#ifndef MS_WINDOWS
1419 && !path->narrow
1420#endif
1421 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001422 PyErr_Format(PyExc_ValueError,
1423 "%s: can't specify dir_fd without matching path",
1424 function_name);
1425 return 1;
1426 }
1427 return 0;
1428}
1429
1430static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001431dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1432{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001433 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1434 PyErr_Format(PyExc_ValueError,
1435 "%s: can't specify both dir_fd and fd",
1436 function_name);
1437 return 1;
1438 }
1439 return 0;
1440}
1441
1442static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001443fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1444 int follow_symlinks)
1445{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001446 if ((fd > 0) && (!follow_symlinks)) {
1447 PyErr_Format(PyExc_ValueError,
1448 "%s: cannot use fd and follow_symlinks together",
1449 function_name);
1450 return 1;
1451 }
1452 return 0;
1453}
1454
1455static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001456dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1457 int follow_symlinks)
1458{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001459 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1460 PyErr_Format(PyExc_ValueError,
1461 "%s: cannot use dir_fd and follow_symlinks together",
1462 function_name);
1463 return 1;
1464 }
1465 return 0;
1466}
1467
Larry Hastings2f936352014-08-05 14:04:04 +10001468#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001469 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001470#else
Larry Hastings2f936352014-08-05 14:04:04 +10001471 typedef off_t Py_off_t;
1472#endif
1473
1474static int
1475Py_off_t_converter(PyObject *arg, void *addr)
1476{
1477#ifdef HAVE_LARGEFILE_SUPPORT
1478 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1479#else
1480 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001481#endif
1482 if (PyErr_Occurred())
1483 return 0;
1484 return 1;
1485}
Larry Hastings2f936352014-08-05 14:04:04 +10001486
1487static PyObject *
1488PyLong_FromPy_off_t(Py_off_t offset)
1489{
1490#ifdef HAVE_LARGEFILE_SUPPORT
1491 return PyLong_FromLongLong(offset);
1492#else
1493 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001494#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001495}
1496
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001497#ifdef HAVE_SIGSET_T
1498/* Convert an iterable of integers to a sigset.
1499 Return 1 on success, return 0 and raise an exception on error. */
1500int
1501_Py_Sigset_Converter(PyObject *obj, void *addr)
1502{
1503 sigset_t *mask = (sigset_t *)addr;
1504 PyObject *iterator, *item;
1505 long signum;
1506 int overflow;
1507
Rémi Lapeyref0900192019-05-04 01:30:53 +02001508 // The extra parens suppress the unreachable-code warning with clang on MacOS
1509 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001510 /* Probably only if mask == NULL. */
1511 PyErr_SetFromErrno(PyExc_OSError);
1512 return 0;
1513 }
1514
1515 iterator = PyObject_GetIter(obj);
1516 if (iterator == NULL) {
1517 return 0;
1518 }
1519
1520 while ((item = PyIter_Next(iterator)) != NULL) {
1521 signum = PyLong_AsLongAndOverflow(item, &overflow);
1522 Py_DECREF(item);
1523 if (signum <= 0 || signum >= NSIG) {
1524 if (overflow || signum != -1 || !PyErr_Occurred()) {
1525 PyErr_Format(PyExc_ValueError,
1526 "signal number %ld out of range", signum);
1527 }
1528 goto error;
1529 }
1530 if (sigaddset(mask, (int)signum)) {
1531 if (errno != EINVAL) {
1532 /* Probably impossible */
1533 PyErr_SetFromErrno(PyExc_OSError);
1534 goto error;
1535 }
1536 /* For backwards compatibility, allow idioms such as
1537 * `range(1, NSIG)` but warn about invalid signal numbers
1538 */
1539 const char msg[] =
1540 "invalid signal number %ld, please use valid_signals()";
1541 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1542 goto error;
1543 }
1544 }
1545 }
1546 if (!PyErr_Occurred()) {
1547 Py_DECREF(iterator);
1548 return 1;
1549 }
1550
1551error:
1552 Py_DECREF(iterator);
1553 return 0;
1554}
1555#endif /* HAVE_SIGSET_T */
1556
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001557#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001558
1559static int
Brian Curtind25aef52011-06-13 15:16:04 -05001560win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001561{
Martin Panter70214ad2016-08-04 02:38:59 +00001562 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1563 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001564 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001565
1566 if (0 == DeviceIoControl(
1567 reparse_point_handle,
1568 FSCTL_GET_REPARSE_POINT,
1569 NULL, 0, /* in buffer */
1570 target_buffer, sizeof(target_buffer),
1571 &n_bytes_returned,
1572 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001573 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001574
1575 if (reparse_tag)
1576 *reparse_tag = rdb->ReparseTag;
1577
Brian Curtind25aef52011-06-13 15:16:04 -05001578 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001579}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001580
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001581#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001582
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001583/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001584#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001585/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001586** environ directly, we must obtain it with _NSGetEnviron(). See also
1587** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001588*/
1589#include <crt_externs.h>
pxinwrf2d7ac72019-05-21 18:46:37 +08001590#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001591extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001592#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001593
Barry Warsaw53699e91996-12-10 23:23:01 +00001594static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001595convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001596{
Victor Stinner8c62be82010-05-06 00:08:46 +00001597 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001598#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001599 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001600#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001601 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001602#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001603
Victor Stinner8c62be82010-05-06 00:08:46 +00001604 d = PyDict_New();
1605 if (d == NULL)
1606 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001607#ifdef MS_WINDOWS
1608 /* _wenviron must be initialized in this way if the program is started
1609 through main() instead of wmain(). */
1610 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001611 e = _wenviron;
Benoit Hudson723f71a2019-12-06 14:15:03 -05001612#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1613 /* environ is not accessible as an extern in a shared object on OSX; use
1614 _NSGetEnviron to resolve it. The value changes if you add environment
1615 variables between calls to Py_Initialize, so don't cache the value. */
1616 e = *_NSGetEnviron();
Victor Stinner8c62be82010-05-06 00:08:46 +00001617#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001618 e = environ;
1619#endif
1620 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001621 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001622 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001623 PyObject *k;
1624 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001625#ifdef MS_WINDOWS
1626 const wchar_t *p = wcschr(*e, L'=');
1627#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001628 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001629#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001630 if (p == NULL)
1631 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001632#ifdef MS_WINDOWS
1633 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1634#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001635 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001636#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001637 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001638 Py_DECREF(d);
1639 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001640 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001641#ifdef MS_WINDOWS
1642 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1643#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001644 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001645#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001646 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001647 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001648 Py_DECREF(d);
1649 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001650 }
Serhiy Storchakab510e102020-10-26 12:47:57 +02001651 if (PyDict_SetDefault(d, k, v) == NULL) {
1652 Py_DECREF(v);
1653 Py_DECREF(k);
1654 Py_DECREF(d);
1655 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001656 }
1657 Py_DECREF(k);
1658 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001659 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001660 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001661}
1662
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001663/* Set a POSIX-specific error from errno, and return NULL */
1664
Barry Warsawd58d7641998-07-23 16:14:40 +00001665static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001666posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001667{
Victor Stinner8c62be82010-05-06 00:08:46 +00001668 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001669}
Mark Hammondef8b6542001-05-13 08:04:26 +00001670
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001671#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001672static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001673win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001674{
Victor Stinner8c62be82010-05-06 00:08:46 +00001675 /* XXX We should pass the function name along in the future.
1676 (winreg.c also wants to pass the function name.)
1677 This would however require an additional param to the
1678 Windows error object, which is non-trivial.
1679 */
1680 errno = GetLastError();
1681 if (filename)
1682 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1683 else
1684 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001685}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001686
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001687static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001688win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001689{
1690 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001691 if (filename)
1692 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001693 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001694 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001695 filename);
1696 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001697 return PyErr_SetFromWindowsErr(err);
1698}
1699
1700static PyObject *
1701win32_error_object(const char* function, PyObject* filename)
1702{
1703 errno = GetLastError();
1704 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001705}
1706
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001707#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001708
Larry Hastings9cf065c2012-06-22 16:30:09 -07001709static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001710posix_path_object_error(PyObject *path)
1711{
1712 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1713}
1714
1715static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001716path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001717{
1718#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001719 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1720 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001721#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001722 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001723#endif
1724}
1725
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001726static PyObject *
1727path_object_error2(PyObject *path, PyObject *path2)
1728{
1729#ifdef MS_WINDOWS
1730 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1731 PyExc_OSError, 0, path, path2);
1732#else
1733 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1734#endif
1735}
1736
1737static PyObject *
1738path_error(path_t *path)
1739{
1740 return path_object_error(path->object);
1741}
Larry Hastings31826802013-10-19 00:09:25 -07001742
Larry Hastingsb0827312014-02-09 22:05:19 -08001743static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001744posix_path_error(path_t *path)
1745{
1746 return posix_path_object_error(path->object);
1747}
1748
1749static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001750path_error2(path_t *path, path_t *path2)
1751{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001752 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001753}
1754
1755
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001756/* POSIX generic methods */
1757
Larry Hastings2f936352014-08-05 14:04:04 +10001758static PyObject *
1759posix_fildes_fd(int fd, int (*func)(int))
1760{
1761 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001762 int async_err = 0;
1763
1764 do {
1765 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001766 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001767 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001768 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001769 Py_END_ALLOW_THREADS
1770 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1771 if (res != 0)
1772 return (!async_err) ? posix_error() : NULL;
1773 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001774}
Guido van Rossum21142a01999-01-08 21:05:37 +00001775
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001776
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001777#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001778/* This is a reimplementation of the C library's chdir function,
1779 but one that produces Win32 errors instead of DOS error codes.
1780 chdir is essentially a wrapper around SetCurrentDirectory; however,
1781 it also needs to set "magic" environment variables indicating
1782 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001783static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001784win32_wchdir(LPCWSTR path)
1785{
Victor Stinnered537822015-12-13 21:40:26 +01001786 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001787 int result;
1788 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001789
Victor Stinner8c62be82010-05-06 00:08:46 +00001790 if(!SetCurrentDirectoryW(path))
1791 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001792 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001793 if (!result)
1794 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001795 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001796 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 if (!new_path) {
1798 SetLastError(ERROR_OUTOFMEMORY);
1799 return FALSE;
1800 }
1801 result = GetCurrentDirectoryW(result, new_path);
1802 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001803 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001804 return FALSE;
1805 }
1806 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001807 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1808 wcsncmp(new_path, L"//", 2) == 0);
1809 if (!is_unc_like_path) {
1810 env[1] = new_path[0];
1811 result = SetEnvironmentVariableW(env, new_path);
1812 }
Victor Stinnered537822015-12-13 21:40:26 +01001813 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001814 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001815 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001816}
1817#endif
1818
Martin v. Löwis14694662006-02-03 12:54:16 +00001819#ifdef MS_WINDOWS
1820/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1821 - time stamps are restricted to second resolution
1822 - file modification times suffer from forth-and-back conversions between
1823 UTC and local time
1824 Therefore, we implement our own stat, based on the Win32 API directly.
1825*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001826#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001827#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001828#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001829
Victor Stinner6036e442015-03-08 01:58:04 +01001830static void
Steve Dowercc16be82016-09-08 10:35:16 -07001831find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1832 BY_HANDLE_FILE_INFORMATION *info,
1833 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001834{
1835 memset(info, 0, sizeof(*info));
1836 info->dwFileAttributes = pFileData->dwFileAttributes;
1837 info->ftCreationTime = pFileData->ftCreationTime;
1838 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1839 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1840 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1841 info->nFileSizeLow = pFileData->nFileSizeLow;
1842/* info->nNumberOfLinks = 1; */
1843 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1844 *reparse_tag = pFileData->dwReserved0;
1845 else
1846 *reparse_tag = 0;
1847}
1848
Guido van Rossumd8faa362007-04-27 19:54:29 +00001849static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001850attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001851{
Victor Stinner8c62be82010-05-06 00:08:46 +00001852 HANDLE hFindFile;
1853 WIN32_FIND_DATAW FileData;
Steve Dowerfe63a402021-04-22 20:45:02 +01001854 LPCWSTR filename = pszFile;
1855 size_t n = wcslen(pszFile);
1856 if (n && (pszFile[n - 1] == L'\\' || pszFile[n - 1] == L'/')) {
1857 // cannot use PyMem_Malloc here because we do not hold the GIL
1858 filename = (LPCWSTR)malloc((n + 1) * sizeof(filename[0]));
1859 wcsncpy_s((LPWSTR)filename, n + 1, pszFile, n);
1860 while (--n > 0 && (filename[n] == L'\\' || filename[n] == L'/')) {
1861 ((LPWSTR)filename)[n] = L'\0';
1862 }
Steve Dowere07d8092021-04-23 00:30:37 +01001863 if (!n || (n == 1 && filename[1] == L':')) {
1864 // Nothing left to query
Steve Dowerfe63a402021-04-22 20:45:02 +01001865 free((void *)filename);
1866 return FALSE;
1867 }
1868 }
1869 hFindFile = FindFirstFileW(filename, &FileData);
1870 if (pszFile != filename) {
1871 free((void *)filename);
1872 }
1873 if (hFindFile == INVALID_HANDLE_VALUE) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001874 return FALSE;
Steve Dowerfe63a402021-04-22 20:45:02 +01001875 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001876 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001877 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001878 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001879}
1880
Brian Curtind25aef52011-06-13 15:16:04 -05001881static int
Steve Dowercc16be82016-09-08 10:35:16 -07001882win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001883 BOOL traverse)
1884{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001885 HANDLE hFile;
1886 BY_HANDLE_FILE_INFORMATION fileInfo;
1887 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1888 DWORD fileType, error;
1889 BOOL isUnhandledTag = FALSE;
1890 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001891
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001892 DWORD access = FILE_READ_ATTRIBUTES;
1893 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1894 if (!traverse) {
1895 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1896 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001897
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001898 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001899 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001900 /* Either the path doesn't exist, or the caller lacks access. */
1901 error = GetLastError();
1902 switch (error) {
1903 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1904 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1905 /* Try reading the parent directory. */
1906 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1907 /* Cannot read the parent directory. */
1908 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001909 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001910 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001911 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1912 if (traverse ||
1913 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1914 /* The stat call has to traverse but cannot, so fail. */
1915 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001916 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001917 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001918 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001919 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001920
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001921 case ERROR_INVALID_PARAMETER:
1922 /* \\.\con requires read or write access. */
1923 hFile = CreateFileW(path, access | GENERIC_READ,
1924 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1925 OPEN_EXISTING, flags, NULL);
1926 if (hFile == INVALID_HANDLE_VALUE) {
1927 SetLastError(error);
1928 return -1;
1929 }
1930 break;
1931
1932 case ERROR_CANT_ACCESS_FILE:
1933 /* bpo37834: open unhandled reparse points if traverse fails. */
1934 if (traverse) {
1935 traverse = FALSE;
1936 isUnhandledTag = TRUE;
1937 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1938 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1939 }
1940 if (hFile == INVALID_HANDLE_VALUE) {
1941 SetLastError(error);
1942 return -1;
1943 }
1944 break;
1945
1946 default:
1947 return -1;
1948 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001949 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001950
1951 if (hFile != INVALID_HANDLE_VALUE) {
1952 /* Handle types other than files on disk. */
1953 fileType = GetFileType(hFile);
1954 if (fileType != FILE_TYPE_DISK) {
1955 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1956 retval = -1;
1957 goto cleanup;
1958 }
1959 DWORD fileAttributes = GetFileAttributesW(path);
1960 memset(result, 0, sizeof(*result));
1961 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1962 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1963 /* \\.\pipe\ or \\.\mailslot\ */
1964 result->st_mode = _S_IFDIR;
1965 } else if (fileType == FILE_TYPE_CHAR) {
1966 /* \\.\nul */
1967 result->st_mode = _S_IFCHR;
1968 } else if (fileType == FILE_TYPE_PIPE) {
1969 /* \\.\pipe\spam */
1970 result->st_mode = _S_IFIFO;
1971 }
1972 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1973 goto cleanup;
1974 }
1975
1976 /* Query the reparse tag, and traverse a non-link. */
1977 if (!traverse) {
1978 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1979 &tagInfo, sizeof(tagInfo))) {
1980 /* Allow devices that do not support FileAttributeTagInfo. */
1981 switch (GetLastError()) {
1982 case ERROR_INVALID_PARAMETER:
1983 case ERROR_INVALID_FUNCTION:
1984 case ERROR_NOT_SUPPORTED:
1985 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1986 tagInfo.ReparseTag = 0;
1987 break;
1988 default:
1989 retval = -1;
1990 goto cleanup;
1991 }
1992 } else if (tagInfo.FileAttributes &
1993 FILE_ATTRIBUTE_REPARSE_POINT) {
1994 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1995 if (isUnhandledTag) {
1996 /* Traversing previously failed for either this link
1997 or its target. */
1998 SetLastError(ERROR_CANT_ACCESS_FILE);
1999 retval = -1;
2000 goto cleanup;
2001 }
2002 /* Traverse a non-link, but not if traversing already failed
2003 for an unhandled tag. */
2004 } else if (!isUnhandledTag) {
2005 CloseHandle(hFile);
2006 return win32_xstat_impl(path, result, TRUE);
2007 }
2008 }
2009 }
2010
2011 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
2012 switch (GetLastError()) {
2013 case ERROR_INVALID_PARAMETER:
2014 case ERROR_INVALID_FUNCTION:
2015 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07002016 /* Volumes and physical disks are block devices, e.g.
2017 \\.\C: and \\.\PhysicalDrive0. */
2018 memset(result, 0, sizeof(*result));
2019 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002020 goto cleanup;
2021 }
Steve Dower772ec0f2019-09-04 14:42:54 -07002022 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002023 goto cleanup;
2024 }
2025 }
2026
2027 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
2028
2029 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
2030 /* Fix the file execute permissions. This hack sets S_IEXEC if
2031 the filename has an extension that is commonly used by files
2032 that CreateProcessW can execute. A real implementation calls
2033 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
2034 AccessCheck to check for generic read, write, and execute
2035 access. */
2036 const wchar_t *fileExtension = wcsrchr(path, '.');
2037 if (fileExtension) {
2038 if (_wcsicmp(fileExtension, L".exe") == 0 ||
2039 _wcsicmp(fileExtension, L".bat") == 0 ||
2040 _wcsicmp(fileExtension, L".cmd") == 0 ||
2041 _wcsicmp(fileExtension, L".com") == 0) {
2042 result->st_mode |= 0111;
2043 }
2044 }
2045 }
2046
2047cleanup:
2048 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07002049 /* Preserve last error if we are failing */
2050 error = retval ? GetLastError() : 0;
2051 if (!CloseHandle(hFile)) {
2052 retval = -1;
2053 } else if (retval) {
2054 /* Restore last error */
2055 SetLastError(error);
2056 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002057 }
2058
2059 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00002060}
2061
2062static int
Steve Dowercc16be82016-09-08 10:35:16 -07002063win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00002064{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002065 /* Protocol violation: we explicitly clear errno, instead of
2066 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05002067 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002068 errno = 0;
2069 return code;
2070}
Brian Curtind25aef52011-06-13 15:16:04 -05002071/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00002072
2073 In Posix, stat automatically traverses symlinks and returns the stat
2074 structure for the target. In Windows, the equivalent GetFileAttributes by
2075 default does not traverse symlinks and instead returns attributes for
2076 the symlink.
2077
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002078 Instead, we will open the file (which *does* traverse symlinks by default)
2079 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00002080
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002081static int
Steve Dowercc16be82016-09-08 10:35:16 -07002082win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00002083{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002084 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00002085}
2086
Victor Stinner8c62be82010-05-06 00:08:46 +00002087static int
Steve Dowercc16be82016-09-08 10:35:16 -07002088win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00002089{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002090 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00002091}
2092
Martin v. Löwis14694662006-02-03 12:54:16 +00002093#endif /* MS_WINDOWS */
2094
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002095PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002096"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002097This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002098 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002099or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
2100\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002101Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
2102or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002103\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002104See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002105
2106static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002107 {"st_mode", "protection bits"},
2108 {"st_ino", "inode"},
2109 {"st_dev", "device"},
2110 {"st_nlink", "number of hard links"},
2111 {"st_uid", "user ID of owner"},
2112 {"st_gid", "group ID of owner"},
2113 {"st_size", "total size, in bytes"},
2114 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
2115 {NULL, "integer time of last access"},
2116 {NULL, "integer time of last modification"},
2117 {NULL, "integer time of last change"},
2118 {"st_atime", "time of last access"},
2119 {"st_mtime", "time of last modification"},
2120 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07002121 {"st_atime_ns", "time of last access in nanoseconds"},
2122 {"st_mtime_ns", "time of last modification in nanoseconds"},
2123 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002124#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002125 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002126#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002127#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002128 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002129#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002130#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002131 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002132#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002133#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002134 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002135#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002136#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002137 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002138#endif
2139#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002141#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002142#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2143 {"st_file_attributes", "Windows file attribute bits"},
2144#endif
jcea6c51d512018-01-28 14:00:08 +01002145#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2146 {"st_fstype", "Type of filesystem"},
2147#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002148#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2149 {"st_reparse_tag", "Windows reparse tag"},
2150#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002151 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002152};
2153
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002154#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002155#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002156#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002157#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002158#endif
2159
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002160#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002161#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2162#else
2163#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2164#endif
2165
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002166#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002167#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2168#else
2169#define ST_RDEV_IDX ST_BLOCKS_IDX
2170#endif
2171
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002172#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2173#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2174#else
2175#define ST_FLAGS_IDX ST_RDEV_IDX
2176#endif
2177
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002178#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002179#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002180#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002181#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002182#endif
2183
2184#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2185#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2186#else
2187#define ST_BIRTHTIME_IDX ST_GEN_IDX
2188#endif
2189
Zachary Ware63f277b2014-06-19 09:46:37 -05002190#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2191#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2192#else
2193#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2194#endif
2195
jcea6c51d512018-01-28 14:00:08 +01002196#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2197#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2198#else
2199#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2200#endif
2201
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002202#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2203#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2204#else
2205#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2206#endif
2207
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002208static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002209 "stat_result", /* name */
2210 stat_result__doc__, /* doc */
2211 stat_result_fields,
2212 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002213};
2214
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002215PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002216"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2217This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002218 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002219or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002220\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002221See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002222
2223static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002224 {"f_bsize", },
2225 {"f_frsize", },
2226 {"f_blocks", },
2227 {"f_bfree", },
2228 {"f_bavail", },
2229 {"f_files", },
2230 {"f_ffree", },
2231 {"f_favail", },
2232 {"f_flag", },
2233 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002234 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002235 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002236};
2237
2238static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002239 "statvfs_result", /* name */
2240 statvfs_result__doc__, /* doc */
2241 statvfs_result_fields,
2242 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002243};
2244
Ross Lagerwall7807c352011-03-17 20:20:30 +02002245#if defined(HAVE_WAITID) && !defined(__APPLE__)
2246PyDoc_STRVAR(waitid_result__doc__,
2247"waitid_result: Result from waitid.\n\n\
2248This object may be accessed either as a tuple of\n\
2249 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2250or via the attributes si_pid, si_uid, and so on.\n\
2251\n\
2252See os.waitid for more information.");
2253
2254static PyStructSequence_Field waitid_result_fields[] = {
2255 {"si_pid", },
2256 {"si_uid", },
2257 {"si_signo", },
2258 {"si_status", },
2259 {"si_code", },
2260 {0}
2261};
2262
2263static PyStructSequence_Desc waitid_result_desc = {
2264 "waitid_result", /* name */
2265 waitid_result__doc__, /* doc */
2266 waitid_result_fields,
2267 5
2268};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002269#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002270static newfunc structseq_new;
2271
2272static PyObject *
2273statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2274{
Victor Stinner8c62be82010-05-06 00:08:46 +00002275 PyStructSequence *result;
2276 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002277
Victor Stinner8c62be82010-05-06 00:08:46 +00002278 result = (PyStructSequence*)structseq_new(type, args, kwds);
2279 if (!result)
2280 return NULL;
2281 /* If we have been initialized from a tuple,
2282 st_?time might be set to None. Initialize it
2283 from the int slots. */
2284 for (i = 7; i <= 9; i++) {
2285 if (result->ob_item[i+3] == Py_None) {
2286 Py_DECREF(Py_None);
2287 Py_INCREF(result->ob_item[i]);
2288 result->ob_item[i+3] = result->ob_item[i];
2289 }
2290 }
2291 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002292}
2293
Eddie Elizondob3966632019-11-05 07:16:14 -08002294static int
2295_posix_clear(PyObject *module)
2296{
Victor Stinner97f33c32020-05-14 18:05:58 +02002297 _posixstate *state = get_posix_state(module);
2298 Py_CLEAR(state->billion);
2299 Py_CLEAR(state->DirEntryType);
2300 Py_CLEAR(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002301#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002302 Py_CLEAR(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002303#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002304 Py_CLEAR(state->StatResultType);
2305 Py_CLEAR(state->StatVFSResultType);
2306 Py_CLEAR(state->TerminalSizeType);
2307 Py_CLEAR(state->TimesResultType);
2308 Py_CLEAR(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002309#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002310 Py_CLEAR(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002311#endif
2312#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002313 Py_CLEAR(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002314#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002315 Py_CLEAR(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002316 return 0;
2317}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002318
Eddie Elizondob3966632019-11-05 07:16:14 -08002319static int
2320_posix_traverse(PyObject *module, visitproc visit, void *arg)
2321{
Victor Stinner97f33c32020-05-14 18:05:58 +02002322 _posixstate *state = get_posix_state(module);
2323 Py_VISIT(state->billion);
2324 Py_VISIT(state->DirEntryType);
2325 Py_VISIT(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002326#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002327 Py_VISIT(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002328#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002329 Py_VISIT(state->StatResultType);
2330 Py_VISIT(state->StatVFSResultType);
2331 Py_VISIT(state->TerminalSizeType);
2332 Py_VISIT(state->TimesResultType);
2333 Py_VISIT(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002334#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002335 Py_VISIT(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002336#endif
2337#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002338 Py_VISIT(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002339#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002340 Py_VISIT(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002341 return 0;
2342}
2343
2344static void
2345_posix_free(void *module)
2346{
2347 _posix_clear((PyObject *)module);
2348}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002349
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002350static void
Victor Stinner1c2fa782020-05-10 11:05:29 +02002351fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002352{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002353 PyObject *s = _PyLong_FromTime_t(sec);
2354 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2355 PyObject *s_in_ns = NULL;
2356 PyObject *ns_total = NULL;
2357 PyObject *float_s = NULL;
2358
2359 if (!(s && ns_fractional))
2360 goto exit;
2361
Victor Stinner1c2fa782020-05-10 11:05:29 +02002362 s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002363 if (!s_in_ns)
2364 goto exit;
2365
2366 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2367 if (!ns_total)
2368 goto exit;
2369
Victor Stinner01b5aab2017-10-24 02:02:00 -07002370 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2371 if (!float_s) {
2372 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002373 }
2374
2375 PyStructSequence_SET_ITEM(v, index, s);
2376 PyStructSequence_SET_ITEM(v, index+3, float_s);
2377 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2378 s = NULL;
2379 float_s = NULL;
2380 ns_total = NULL;
2381exit:
2382 Py_XDECREF(s);
2383 Py_XDECREF(ns_fractional);
2384 Py_XDECREF(s_in_ns);
2385 Py_XDECREF(ns_total);
2386 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002387}
2388
Tim Peters5aa91602002-01-30 05:46:57 +00002389/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002390 (used by posix_stat() and posix_fstat()) */
2391static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +02002392_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002393{
Victor Stinner8c62be82010-05-06 00:08:46 +00002394 unsigned long ansec, mnsec, cnsec;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002395 PyObject *StatResultType = get_posix_state(module)->StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08002396 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002397 if (v == NULL)
2398 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002399
Victor Stinner8c62be82010-05-06 00:08:46 +00002400 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002401 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002402 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002403#ifdef MS_WINDOWS
2404 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002405#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002406 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002407#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002408 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002409#if defined(MS_WINDOWS)
2410 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2411 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2412#else
2413 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2414 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2415#endif
xdegaye50e86032017-05-22 11:15:08 +02002416 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2417 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002418
Martin v. Löwis14694662006-02-03 12:54:16 +00002419#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002420 ansec = st->st_atim.tv_nsec;
2421 mnsec = st->st_mtim.tv_nsec;
2422 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002423#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002424 ansec = st->st_atimespec.tv_nsec;
2425 mnsec = st->st_mtimespec.tv_nsec;
2426 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002427#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002428 ansec = st->st_atime_nsec;
2429 mnsec = st->st_mtime_nsec;
2430 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002431#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002432 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002433#endif
Victor Stinner1c2fa782020-05-10 11:05:29 +02002434 fill_time(module, v, 7, st->st_atime, ansec);
2435 fill_time(module, v, 8, st->st_mtime, mnsec);
2436 fill_time(module, v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002437
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002438#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002439 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2440 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002441#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002442#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002443 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2444 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002445#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002446#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002447 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2448 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002449#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002450#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002451 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2452 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002453#endif
2454#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002455 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002456 PyObject *val;
2457 unsigned long bsec,bnsec;
2458 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002459#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002460 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002461#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002462 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002463#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002464 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002465 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2466 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002467 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002468#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002469#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002470 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2471 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002472#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002473#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2474 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2475 PyLong_FromUnsignedLong(st->st_file_attributes));
2476#endif
jcea6c51d512018-01-28 14:00:08 +01002477#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2478 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2479 PyUnicode_FromString(st->st_fstype));
2480#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002481#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2482 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2483 PyLong_FromUnsignedLong(st->st_reparse_tag));
2484#endif
Fred Drake699f3522000-06-29 21:12:41 +00002485
Victor Stinner8c62be82010-05-06 00:08:46 +00002486 if (PyErr_Occurred()) {
2487 Py_DECREF(v);
2488 return NULL;
2489 }
Fred Drake699f3522000-06-29 21:12:41 +00002490
Victor Stinner8c62be82010-05-06 00:08:46 +00002491 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002492}
2493
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002494/* POSIX methods */
2495
Guido van Rossum94f6f721999-01-06 18:42:14 +00002496
2497static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02002498posix_do_stat(PyObject *module, const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002499 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002500{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002501 STRUCT_STAT st;
2502 int result;
2503
Ronald Oussoren41761932020-11-08 10:05:27 +01002504#ifdef HAVE_FSTATAT
2505 int fstatat_unavailable = 0;
2506#endif
2507
Larry Hastings9cf065c2012-06-22 16:30:09 -07002508#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2509 if (follow_symlinks_specified(function_name, follow_symlinks))
2510 return NULL;
2511#endif
2512
2513 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2514 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2515 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2516 return NULL;
2517
2518 Py_BEGIN_ALLOW_THREADS
2519 if (path->fd != -1)
2520 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002521#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002522 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002523 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002524 else
Steve Dowercc16be82016-09-08 10:35:16 -07002525 result = win32_lstat(path->wide, &st);
2526#else
2527 else
2528#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002529 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2530 result = LSTAT(path->narrow, &st);
2531 else
Steve Dowercc16be82016-09-08 10:35:16 -07002532#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002533#ifdef HAVE_FSTATAT
Ronald Oussoren41761932020-11-08 10:05:27 +01002534 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2535 if (HAVE_FSTATAT_RUNTIME) {
2536 result = fstatat(dir_fd, path->narrow, &st,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002537 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +01002538
2539 } else {
2540 fstatat_unavailable = 1;
2541 }
2542 } else
Steve Dowercc16be82016-09-08 10:35:16 -07002543#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002544 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002545#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002546 Py_END_ALLOW_THREADS
2547
Ronald Oussoren41761932020-11-08 10:05:27 +01002548#ifdef HAVE_FSTATAT
2549 if (fstatat_unavailable) {
2550 argument_unavailable_error("stat", "dir_fd");
2551 return NULL;
2552 }
2553#endif
2554
Victor Stinner292c8352012-10-30 02:17:38 +01002555 if (result != 0) {
2556 return path_error(path);
2557 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002558
Victor Stinner1c2fa782020-05-10 11:05:29 +02002559 return _pystat_fromstructstat(module, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002560}
2561
Larry Hastings2f936352014-08-05 14:04:04 +10002562/*[python input]
2563
2564for s in """
2565
2566FACCESSAT
2567FCHMODAT
2568FCHOWNAT
2569FSTATAT
2570LINKAT
2571MKDIRAT
2572MKFIFOAT
2573MKNODAT
2574OPENAT
2575READLINKAT
2576SYMLINKAT
2577UNLINKAT
2578
2579""".strip().split():
2580 s = s.strip()
2581 print("""
2582#ifdef HAVE_{s}
2583 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002584#else
Larry Hastings2f936352014-08-05 14:04:04 +10002585 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002586#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002587""".rstrip().format(s=s))
2588
2589for s in """
2590
2591FCHDIR
2592FCHMOD
2593FCHOWN
2594FDOPENDIR
2595FEXECVE
2596FPATHCONF
2597FSTATVFS
2598FTRUNCATE
2599
2600""".strip().split():
2601 s = s.strip()
2602 print("""
2603#ifdef HAVE_{s}
2604 #define PATH_HAVE_{s} 1
2605#else
2606 #define PATH_HAVE_{s} 0
2607#endif
2608
2609""".rstrip().format(s=s))
2610[python start generated code]*/
2611
2612#ifdef HAVE_FACCESSAT
2613 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2614#else
2615 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2616#endif
2617
2618#ifdef HAVE_FCHMODAT
2619 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2620#else
2621 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2622#endif
2623
2624#ifdef HAVE_FCHOWNAT
2625 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2626#else
2627 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2628#endif
2629
2630#ifdef HAVE_FSTATAT
2631 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2632#else
2633 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2634#endif
2635
2636#ifdef HAVE_LINKAT
2637 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2638#else
2639 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2640#endif
2641
2642#ifdef HAVE_MKDIRAT
2643 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2644#else
2645 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2646#endif
2647
2648#ifdef HAVE_MKFIFOAT
2649 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2650#else
2651 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2652#endif
2653
2654#ifdef HAVE_MKNODAT
2655 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2656#else
2657 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2658#endif
2659
2660#ifdef HAVE_OPENAT
2661 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2662#else
2663 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2664#endif
2665
2666#ifdef HAVE_READLINKAT
2667 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2668#else
2669 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2670#endif
2671
2672#ifdef HAVE_SYMLINKAT
2673 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2674#else
2675 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2676#endif
2677
2678#ifdef HAVE_UNLINKAT
2679 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2680#else
2681 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2682#endif
2683
2684#ifdef HAVE_FCHDIR
2685 #define PATH_HAVE_FCHDIR 1
2686#else
2687 #define PATH_HAVE_FCHDIR 0
2688#endif
2689
2690#ifdef HAVE_FCHMOD
2691 #define PATH_HAVE_FCHMOD 1
2692#else
2693 #define PATH_HAVE_FCHMOD 0
2694#endif
2695
2696#ifdef HAVE_FCHOWN
2697 #define PATH_HAVE_FCHOWN 1
2698#else
2699 #define PATH_HAVE_FCHOWN 0
2700#endif
2701
2702#ifdef HAVE_FDOPENDIR
2703 #define PATH_HAVE_FDOPENDIR 1
2704#else
2705 #define PATH_HAVE_FDOPENDIR 0
2706#endif
2707
2708#ifdef HAVE_FEXECVE
2709 #define PATH_HAVE_FEXECVE 1
2710#else
2711 #define PATH_HAVE_FEXECVE 0
2712#endif
2713
2714#ifdef HAVE_FPATHCONF
2715 #define PATH_HAVE_FPATHCONF 1
2716#else
2717 #define PATH_HAVE_FPATHCONF 0
2718#endif
2719
2720#ifdef HAVE_FSTATVFS
2721 #define PATH_HAVE_FSTATVFS 1
2722#else
2723 #define PATH_HAVE_FSTATVFS 0
2724#endif
2725
2726#ifdef HAVE_FTRUNCATE
2727 #define PATH_HAVE_FTRUNCATE 1
2728#else
2729 #define PATH_HAVE_FTRUNCATE 0
2730#endif
2731/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002732
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002733#ifdef MS_WINDOWS
2734 #undef PATH_HAVE_FTRUNCATE
2735 #define PATH_HAVE_FTRUNCATE 1
2736#endif
Larry Hastings31826802013-10-19 00:09:25 -07002737
Larry Hastings61272b72014-01-07 12:41:53 -08002738/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002739
2740class path_t_converter(CConverter):
2741
2742 type = "path_t"
2743 impl_by_reference = True
2744 parse_by_reference = True
2745
2746 converter = 'path_converter'
2747
2748 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002749 # right now path_t doesn't support default values.
2750 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002751 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002752 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002753
Larry Hastings2f936352014-08-05 14:04:04 +10002754 if self.c_default not in (None, 'Py_None'):
2755 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002756
2757 self.nullable = nullable
2758 self.allow_fd = allow_fd
2759
Larry Hastings7726ac92014-01-31 22:03:12 -08002760 def pre_render(self):
2761 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002762 if isinstance(value, str):
2763 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002764 return str(int(bool(value)))
2765
2766 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002767 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002768 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002769 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002770 strify(self.nullable),
2771 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002772 )
2773
2774 def cleanup(self):
2775 return "path_cleanup(&" + self.name + ");\n"
2776
2777
2778class dir_fd_converter(CConverter):
2779 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002780
Larry Hastings2f936352014-08-05 14:04:04 +10002781 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002782 if self.default in (unspecified, None):
2783 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002784 if isinstance(requires, str):
2785 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2786 else:
2787 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002788
Larry Hastings2f936352014-08-05 14:04:04 +10002789class uid_t_converter(CConverter):
2790 type = "uid_t"
2791 converter = '_Py_Uid_Converter'
2792
2793class gid_t_converter(CConverter):
2794 type = "gid_t"
2795 converter = '_Py_Gid_Converter'
2796
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002797class dev_t_converter(CConverter):
2798 type = 'dev_t'
2799 converter = '_Py_Dev_Converter'
2800
2801class dev_t_return_converter(unsigned_long_return_converter):
2802 type = 'dev_t'
2803 conversion_fn = '_PyLong_FromDev'
2804 unsigned_cast = '(dev_t)'
2805
Larry Hastings2f936352014-08-05 14:04:04 +10002806class FSConverter_converter(CConverter):
2807 type = 'PyObject *'
2808 converter = 'PyUnicode_FSConverter'
2809 def converter_init(self):
2810 if self.default is not unspecified:
2811 fail("FSConverter_converter does not support default values")
2812 self.c_default = 'NULL'
2813
2814 def cleanup(self):
2815 return "Py_XDECREF(" + self.name + ");\n"
2816
2817class pid_t_converter(CConverter):
2818 type = 'pid_t'
2819 format_unit = '" _Py_PARSE_PID "'
2820
2821class idtype_t_converter(int_converter):
2822 type = 'idtype_t'
2823
2824class id_t_converter(CConverter):
2825 type = 'id_t'
2826 format_unit = '" _Py_PARSE_PID "'
2827
Benjamin Petersonca470632016-09-06 13:47:26 -07002828class intptr_t_converter(CConverter):
2829 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002830 format_unit = '" _Py_PARSE_INTPTR "'
2831
2832class Py_off_t_converter(CConverter):
2833 type = 'Py_off_t'
2834 converter = 'Py_off_t_converter'
2835
2836class Py_off_t_return_converter(long_return_converter):
2837 type = 'Py_off_t'
2838 conversion_fn = 'PyLong_FromPy_off_t'
2839
2840class path_confname_converter(CConverter):
2841 type="int"
2842 converter="conv_path_confname"
2843
2844class confstr_confname_converter(path_confname_converter):
2845 converter='conv_confstr_confname'
2846
2847class sysconf_confname_converter(path_confname_converter):
2848 converter="conv_sysconf_confname"
2849
Larry Hastings61272b72014-01-07 12:41:53 -08002850[python start generated code]*/
Serhiy Storchaka9975cc52020-10-09 23:00:45 +03002851/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/
Larry Hastings31826802013-10-19 00:09:25 -07002852
Larry Hastings61272b72014-01-07 12:41:53 -08002853/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002854
Larry Hastings2a727912014-01-16 11:32:01 -08002855os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002856
2857 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002858 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002859 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002860
2861 *
2862
Larry Hastings2f936352014-08-05 14:04:04 +10002863 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002864 If not None, it should be a file descriptor open to a directory,
2865 and path should be a relative string; path will then be relative to
2866 that directory.
2867
2868 follow_symlinks: bool = True
2869 If False, and the last element of the path is a symbolic link,
2870 stat will examine the symbolic link itself instead of the file
2871 the link points to.
2872
2873Perform a stat system call on the given path.
2874
2875dir_fd and follow_symlinks may not be implemented
2876 on your platform. If they are unavailable, using them will raise a
2877 NotImplementedError.
2878
2879It's an error to use dir_fd or follow_symlinks when specifying path as
2880 an open file descriptor.
2881
Larry Hastings61272b72014-01-07 12:41:53 -08002882[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002883
Larry Hastings31826802013-10-19 00:09:25 -07002884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002885os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002886/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002887{
Victor Stinner1c2fa782020-05-10 11:05:29 +02002888 return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002889}
2890
Larry Hastings2f936352014-08-05 14:04:04 +10002891
2892/*[clinic input]
2893os.lstat
2894
2895 path : path_t
2896
2897 *
2898
2899 dir_fd : dir_fd(requires='fstatat') = None
2900
2901Perform a stat system call on the given path, without following symbolic links.
2902
2903Like stat(), but do not follow symbolic links.
2904Equivalent to stat(path, follow_symlinks=False).
2905[clinic start generated code]*/
2906
Larry Hastings2f936352014-08-05 14:04:04 +10002907static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002908os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2909/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002910{
2911 int follow_symlinks = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002912 return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10002913}
Larry Hastings31826802013-10-19 00:09:25 -07002914
Larry Hastings2f936352014-08-05 14:04:04 +10002915
Larry Hastings61272b72014-01-07 12:41:53 -08002916/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002917os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002918
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002919 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002920 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002921
2922 mode: int
2923 Operating-system mode bitfield. Can be F_OK to test existence,
2924 or the inclusive-OR of R_OK, W_OK, and X_OK.
2925
2926 *
2927
Larry Hastings2f936352014-08-05 14:04:04 +10002928 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002929 If not None, it should be a file descriptor open to a directory,
2930 and path should be relative; path will then be relative to that
2931 directory.
2932
2933 effective_ids: bool = False
2934 If True, access will use the effective uid/gid instead of
2935 the real uid/gid.
2936
2937 follow_symlinks: bool = True
2938 If False, and the last element of the path is a symbolic link,
2939 access will examine the symbolic link itself instead of the file
2940 the link points to.
2941
2942Use the real uid/gid to test for access to a path.
2943
2944{parameters}
2945dir_fd, effective_ids, and follow_symlinks may not be implemented
2946 on your platform. If they are unavailable, using them will raise a
2947 NotImplementedError.
2948
2949Note that most operations will use the effective uid/gid, therefore this
2950 routine can be used in a suid/sgid environment to test if the invoking user
2951 has the specified access to the path.
2952
Larry Hastings61272b72014-01-07 12:41:53 -08002953[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002954
Larry Hastings2f936352014-08-05 14:04:04 +10002955static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002956os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002957 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002958/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002959{
Larry Hastings2f936352014-08-05 14:04:04 +10002960 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002961
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002962#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002963 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002964#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002965 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002966#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002967
Ronald Oussoren41761932020-11-08 10:05:27 +01002968#ifdef HAVE_FACCESSAT
2969 int faccessat_unavailable = 0;
2970#endif
2971
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972#ifndef HAVE_FACCESSAT
2973 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002974 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002975
2976 if (effective_ids) {
2977 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002978 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002979 }
2980#endif
2981
2982#ifdef MS_WINDOWS
2983 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002984 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002985 Py_END_ALLOW_THREADS
2986
2987 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002988 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002989 * * we didn't get a -1, and
2990 * * write access wasn't requested,
2991 * * or the file isn't read-only,
2992 * * or it's a directory.
2993 * (Directories cannot be read-only on Windows.)
2994 */
Larry Hastings2f936352014-08-05 14:04:04 +10002995 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002996 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002997 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002998 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002999#else
3000
3001 Py_BEGIN_ALLOW_THREADS
3002#ifdef HAVE_FACCESSAT
3003 if ((dir_fd != DEFAULT_DIR_FD) ||
3004 effective_ids ||
3005 !follow_symlinks) {
Ronald Oussoren41761932020-11-08 10:05:27 +01003006
3007 if (HAVE_FACCESSAT_RUNTIME) {
3008 int flags = 0;
3009 if (!follow_symlinks)
3010 flags |= AT_SYMLINK_NOFOLLOW;
3011 if (effective_ids)
3012 flags |= AT_EACCESS;
3013 result = faccessat(dir_fd, path->narrow, mode, flags);
3014 } else {
3015 faccessat_unavailable = 1;
3016 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003017 }
3018 else
3019#endif
Larry Hastings31826802013-10-19 00:09:25 -07003020 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003021 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01003022
3023#ifdef HAVE_FACCESSAT
3024 if (faccessat_unavailable) {
3025 if (dir_fd != DEFAULT_DIR_FD) {
3026 argument_unavailable_error("access", "dir_fd");
3027 return -1;
3028 }
3029 if (follow_symlinks_specified("access", follow_symlinks))
3030 return -1;
3031
3032 if (effective_ids) {
3033 argument_unavailable_error("access", "effective_ids");
3034 return -1;
3035 }
3036 /* should be unreachable */
3037 return -1;
3038 }
3039#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003040 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003041#endif
3042
Larry Hastings9cf065c2012-06-22 16:30:09 -07003043 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003044}
3045
Guido van Rossumd371ff11999-01-25 16:12:23 +00003046#ifndef F_OK
3047#define F_OK 0
3048#endif
3049#ifndef R_OK
3050#define R_OK 4
3051#endif
3052#ifndef W_OK
3053#define W_OK 2
3054#endif
3055#ifndef X_OK
3056#define X_OK 1
3057#endif
3058
Larry Hastings31826802013-10-19 00:09:25 -07003059
Guido van Rossumd371ff11999-01-25 16:12:23 +00003060#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08003061/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003062os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07003063
3064 fd: int
3065 Integer file descriptor handle.
3066
3067 /
3068
3069Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08003070[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07003071
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003072static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003073os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003074/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07003075{
Guido van Rossum94f6f721999-01-06 18:42:14 +00003076
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02003077 long size = sysconf(_SC_TTY_NAME_MAX);
3078 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003079 return posix_error();
3080 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02003081 char *buffer = (char *)PyMem_RawMalloc(size);
3082 if (buffer == NULL) {
3083 return PyErr_NoMemory();
3084 }
3085 int ret = ttyname_r(fd, buffer, size);
3086 if (ret != 0) {
3087 PyMem_RawFree(buffer);
3088 errno = ret;
3089 return posix_error();
3090 }
3091 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
3092 PyMem_RawFree(buffer);
3093 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003094}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003095#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003096
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003097#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10003098/*[clinic input]
3099os.ctermid
3100
3101Return the name of the controlling terminal for this process.
3102[clinic start generated code]*/
3103
Larry Hastings2f936352014-08-05 14:04:04 +10003104static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003105os_ctermid_impl(PyObject *module)
3106/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003107{
Victor Stinner8c62be82010-05-06 00:08:46 +00003108 char *ret;
3109 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003110
Greg Wardb48bc172000-03-01 21:51:56 +00003111#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00003112 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003113#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003114 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003115#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003116 if (ret == NULL)
3117 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00003118 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003119}
Larry Hastings2f936352014-08-05 14:04:04 +10003120#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003121
Larry Hastings2f936352014-08-05 14:04:04 +10003122
3123/*[clinic input]
3124os.chdir
3125
3126 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
3127
3128Change the current working directory to the specified path.
3129
3130path may always be specified as a string.
3131On some platforms, path may also be specified as an open file descriptor.
3132 If this functionality is unavailable, using it raises an exception.
3133[clinic start generated code]*/
3134
Larry Hastings2f936352014-08-05 14:04:04 +10003135static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003136os_chdir_impl(PyObject *module, path_t *path)
3137/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003138{
3139 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003140
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003141 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
3142 return NULL;
3143 }
3144
Larry Hastings9cf065c2012-06-22 16:30:09 -07003145 Py_BEGIN_ALLOW_THREADS
3146#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003147 /* on unix, success = 0, on windows, success = !0 */
3148 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003149#else
3150#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10003151 if (path->fd != -1)
3152 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003153 else
3154#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003155 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156#endif
3157 Py_END_ALLOW_THREADS
3158
3159 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003160 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003161 }
3162
Larry Hastings2f936352014-08-05 14:04:04 +10003163 Py_RETURN_NONE;
3164}
3165
3166
3167#ifdef HAVE_FCHDIR
3168/*[clinic input]
3169os.fchdir
3170
3171 fd: fildes
3172
3173Change to the directory of the given file descriptor.
3174
3175fd must be opened on a directory, not a file.
3176Equivalent to os.chdir(fd).
3177
3178[clinic start generated code]*/
3179
Fred Drake4d1e64b2002-04-15 19:40:07 +00003180static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003181os_fchdir_impl(PyObject *module, int fd)
3182/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00003183{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003184 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
3185 return NULL;
3186 }
Larry Hastings2f936352014-08-05 14:04:04 +10003187 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00003188}
3189#endif /* HAVE_FCHDIR */
3190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003191
Larry Hastings2f936352014-08-05 14:04:04 +10003192/*[clinic input]
3193os.chmod
3194
3195 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00003196 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10003197 On some platforms, path may also be specified as an open file descriptor.
3198 If this functionality is unavailable, using it raises an exception.
3199
3200 mode: int
3201 Operating-system mode bitfield.
3202
3203 *
3204
3205 dir_fd : dir_fd(requires='fchmodat') = None
3206 If not None, it should be a file descriptor open to a directory,
3207 and path should be relative; path will then be relative to that
3208 directory.
3209
3210 follow_symlinks: bool = True
3211 If False, and the last element of the path is a symbolic link,
3212 chmod will modify the symbolic link itself instead of the file
3213 the link points to.
3214
3215Change the access permissions of a file.
3216
3217It is an error to use dir_fd or follow_symlinks when specifying path as
3218 an open file descriptor.
3219dir_fd and follow_symlinks may not be implemented on your platform.
3220 If they are unavailable, using them will raise a NotImplementedError.
3221
3222[clinic start generated code]*/
3223
Larry Hastings2f936352014-08-05 14:04:04 +10003224static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003225os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003226 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003227/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003228{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003229 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003230
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003231#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003233#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003234
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235#ifdef HAVE_FCHMODAT
3236 int fchmodat_nofollow_unsupported = 0;
Ronald Oussoren41761932020-11-08 10:05:27 +01003237 int fchmodat_unsupported = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003238#endif
3239
Larry Hastings9cf065c2012-06-22 16:30:09 -07003240#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3241 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003242 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003243#endif
3244
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003245 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3246 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3247 return NULL;
3248 }
3249
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003251 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003252 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003253 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003254 result = 0;
3255 else {
3256 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 attr &= ~FILE_ATTRIBUTE_READONLY;
3258 else
3259 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003260 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003261 }
3262 Py_END_ALLOW_THREADS
3263
3264 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003265 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003266 }
3267#else /* MS_WINDOWS */
3268 Py_BEGIN_ALLOW_THREADS
3269#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003270 if (path->fd != -1)
3271 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003272 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003273#endif /* HAVE_CHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003274#ifdef HAVE_LCHMOD
3275 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003276 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003277 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003278#endif /* HAVE_LCHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003279#ifdef HAVE_FCHMODAT
3280 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
Ronald Oussoren41761932020-11-08 10:05:27 +01003281 if (HAVE_FCHMODAT_RUNTIME) {
3282 /*
3283 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3284 * The documentation specifically shows how to use it,
3285 * and then says it isn't implemented yet.
3286 * (true on linux with glibc 2.15, and openindiana 3.x)
3287 *
3288 * Once it is supported, os.chmod will automatically
3289 * support dir_fd and follow_symlinks=False. (Hopefully.)
3290 * Until then, we need to be careful what exception we raise.
3291 */
3292 result = fchmodat(dir_fd, path->narrow, mode,
3293 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3294 /*
3295 * But wait! We can't throw the exception without allowing threads,
3296 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3297 */
3298 fchmodat_nofollow_unsupported =
3299 result &&
3300 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3301 !follow_symlinks;
3302 } else {
3303 fchmodat_unsupported = 1;
3304 fchmodat_nofollow_unsupported = 1;
3305
3306 result = -1;
3307 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 }
3309 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003310#endif /* HAVE_FHCMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003311 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003312 Py_END_ALLOW_THREADS
3313
3314 if (result) {
3315#ifdef HAVE_FCHMODAT
Ronald Oussoren41761932020-11-08 10:05:27 +01003316 if (fchmodat_unsupported) {
3317 if (dir_fd != DEFAULT_DIR_FD) {
3318 argument_unavailable_error("chmod", "dir_fd");
3319 return NULL;
3320 }
3321 }
3322
Larry Hastings9cf065c2012-06-22 16:30:09 -07003323 if (fchmodat_nofollow_unsupported) {
3324 if (dir_fd != DEFAULT_DIR_FD)
3325 dir_fd_and_follow_symlinks_invalid("chmod",
3326 dir_fd, follow_symlinks);
3327 else
3328 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003329 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003330 }
3331 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003332#endif /* HAVE_FCHMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003333 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003334 }
Ronald Oussoren41761932020-11-08 10:05:27 +01003335#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003336
Larry Hastings2f936352014-08-05 14:04:04 +10003337 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003338}
3339
Larry Hastings9cf065c2012-06-22 16:30:09 -07003340
Christian Heimes4e30a842007-11-30 22:12:06 +00003341#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003342/*[clinic input]
3343os.fchmod
3344
3345 fd: int
3346 mode: int
3347
3348Change the access permissions of the file given by file descriptor fd.
3349
3350Equivalent to os.chmod(fd, mode).
3351[clinic start generated code]*/
3352
Larry Hastings2f936352014-08-05 14:04:04 +10003353static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003354os_fchmod_impl(PyObject *module, int fd, int mode)
3355/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003356{
3357 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003358 int async_err = 0;
3359
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003360 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3361 return NULL;
3362 }
3363
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003364 do {
3365 Py_BEGIN_ALLOW_THREADS
3366 res = fchmod(fd, mode);
3367 Py_END_ALLOW_THREADS
3368 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3369 if (res != 0)
3370 return (!async_err) ? posix_error() : NULL;
3371
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003373}
3374#endif /* HAVE_FCHMOD */
3375
Larry Hastings2f936352014-08-05 14:04:04 +10003376
Christian Heimes4e30a842007-11-30 22:12:06 +00003377#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003378/*[clinic input]
3379os.lchmod
3380
3381 path: path_t
3382 mode: int
3383
3384Change the access permissions of a file, without following symbolic links.
3385
3386If path is a symlink, this affects the link itself rather than the target.
3387Equivalent to chmod(path, mode, follow_symlinks=False)."
3388[clinic start generated code]*/
3389
Larry Hastings2f936352014-08-05 14:04:04 +10003390static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003391os_lchmod_impl(PyObject *module, path_t *path, int mode)
3392/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003393{
Victor Stinner8c62be82010-05-06 00:08:46 +00003394 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003395 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3396 return NULL;
3397 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003398 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003399 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003401 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003402 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003403 return NULL;
3404 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003406}
3407#endif /* HAVE_LCHMOD */
3408
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003409
Thomas Wouterscf297e42007-02-23 15:07:44 +00003410#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003411/*[clinic input]
3412os.chflags
3413
3414 path: path_t
3415 flags: unsigned_long(bitwise=True)
3416 follow_symlinks: bool=True
3417
3418Set file flags.
3419
3420If follow_symlinks is False, and the last element of the path is a symbolic
3421 link, chflags will change flags on the symbolic link itself instead of the
3422 file the link points to.
3423follow_symlinks may not be implemented on your platform. If it is
3424unavailable, using it will raise a NotImplementedError.
3425
3426[clinic start generated code]*/
3427
Larry Hastings2f936352014-08-05 14:04:04 +10003428static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003429os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003430 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003431/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003432{
3433 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434
3435#ifndef HAVE_LCHFLAGS
3436 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003437 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438#endif
3439
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003440 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3441 return NULL;
3442 }
3443
Victor Stinner8c62be82010-05-06 00:08:46 +00003444 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445#ifdef HAVE_LCHFLAGS
3446 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003447 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448 else
3449#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003450 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452
Larry Hastings2f936352014-08-05 14:04:04 +10003453 if (result)
3454 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455
Larry Hastings2f936352014-08-05 14:04:04 +10003456 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003457}
3458#endif /* HAVE_CHFLAGS */
3459
Larry Hastings2f936352014-08-05 14:04:04 +10003460
Thomas Wouterscf297e42007-02-23 15:07:44 +00003461#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003462/*[clinic input]
3463os.lchflags
3464
3465 path: path_t
3466 flags: unsigned_long(bitwise=True)
3467
3468Set file flags.
3469
3470This function will not follow symbolic links.
3471Equivalent to chflags(path, flags, follow_symlinks=False).
3472[clinic start generated code]*/
3473
Larry Hastings2f936352014-08-05 14:04:04 +10003474static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003475os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3476/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003477{
Victor Stinner8c62be82010-05-06 00:08:46 +00003478 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003479 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3480 return NULL;
3481 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003482 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003483 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003485 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003486 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003487 }
Victor Stinner292c8352012-10-30 02:17:38 +01003488 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003489}
3490#endif /* HAVE_LCHFLAGS */
3491
Larry Hastings2f936352014-08-05 14:04:04 +10003492
Martin v. Löwis244edc82001-10-04 22:44:26 +00003493#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003494/*[clinic input]
3495os.chroot
3496 path: path_t
3497
3498Change root directory to path.
3499
3500[clinic start generated code]*/
3501
Larry Hastings2f936352014-08-05 14:04:04 +10003502static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003503os_chroot_impl(PyObject *module, path_t *path)
3504/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003505{
3506 int res;
3507 Py_BEGIN_ALLOW_THREADS
3508 res = chroot(path->narrow);
3509 Py_END_ALLOW_THREADS
3510 if (res < 0)
3511 return path_error(path);
3512 Py_RETURN_NONE;
3513}
3514#endif /* HAVE_CHROOT */
3515
Martin v. Löwis244edc82001-10-04 22:44:26 +00003516
Guido van Rossum21142a01999-01-08 21:05:37 +00003517#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003518/*[clinic input]
3519os.fsync
3520
3521 fd: fildes
3522
3523Force write of fd to disk.
3524[clinic start generated code]*/
3525
Larry Hastings2f936352014-08-05 14:04:04 +10003526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003527os_fsync_impl(PyObject *module, int fd)
3528/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003529{
3530 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003531}
3532#endif /* HAVE_FSYNC */
3533
Larry Hastings2f936352014-08-05 14:04:04 +10003534
Ross Lagerwall7807c352011-03-17 20:20:30 +02003535#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003536/*[clinic input]
3537os.sync
3538
3539Force write of everything to disk.
3540[clinic start generated code]*/
3541
Larry Hastings2f936352014-08-05 14:04:04 +10003542static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003543os_sync_impl(PyObject *module)
3544/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003545{
3546 Py_BEGIN_ALLOW_THREADS
3547 sync();
3548 Py_END_ALLOW_THREADS
3549 Py_RETURN_NONE;
3550}
Larry Hastings2f936352014-08-05 14:04:04 +10003551#endif /* HAVE_SYNC */
3552
Ross Lagerwall7807c352011-03-17 20:20:30 +02003553
Guido van Rossum21142a01999-01-08 21:05:37 +00003554#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003555#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003556extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3557#endif
3558
Larry Hastings2f936352014-08-05 14:04:04 +10003559/*[clinic input]
3560os.fdatasync
3561
3562 fd: fildes
3563
3564Force write of fd to disk without forcing update of metadata.
3565[clinic start generated code]*/
3566
Larry Hastings2f936352014-08-05 14:04:04 +10003567static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003568os_fdatasync_impl(PyObject *module, int fd)
3569/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003570{
3571 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003572}
3573#endif /* HAVE_FDATASYNC */
3574
3575
Fredrik Lundh10723342000-07-10 16:38:09 +00003576#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003577/*[clinic input]
3578os.chown
3579
3580 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003581 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003582
3583 uid: uid_t
3584
3585 gid: gid_t
3586
3587 *
3588
3589 dir_fd : dir_fd(requires='fchownat') = None
3590 If not None, it should be a file descriptor open to a directory,
3591 and path should be relative; path will then be relative to that
3592 directory.
3593
3594 follow_symlinks: bool = True
3595 If False, and the last element of the path is a symbolic link,
3596 stat will examine the symbolic link itself instead of the file
3597 the link points to.
3598
3599Change the owner and group id of path to the numeric uid and gid.\
3600
3601path may always be specified as a string.
3602On some platforms, path may also be specified as an open file descriptor.
3603 If this functionality is unavailable, using it raises an exception.
3604If dir_fd is not None, it should be a file descriptor open to a directory,
3605 and path should be relative; path will then be relative to that directory.
3606If follow_symlinks is False, and the last element of the path is a symbolic
3607 link, chown will modify the symbolic link itself instead of the file the
3608 link points to.
3609It is an error to use dir_fd or follow_symlinks when specifying path as
3610 an open file descriptor.
3611dir_fd and follow_symlinks may not be implemented on your platform.
3612 If they are unavailable, using them will raise a NotImplementedError.
3613
3614[clinic start generated code]*/
3615
Larry Hastings2f936352014-08-05 14:04:04 +10003616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003617os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003618 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003619/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003620{
3621 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003622
Ronald Oussoren41761932020-11-08 10:05:27 +01003623#if defined(HAVE_FCHOWNAT)
3624 int fchownat_unsupported = 0;
3625#endif
3626
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3628 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003629 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003630#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003631 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3632 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3633 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003635 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3636 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3637 return NULL;
3638 }
3639
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003641#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003642 if (path->fd != -1)
3643 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644 else
3645#endif
3646#ifdef HAVE_LCHOWN
3647 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003648 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003649 else
3650#endif
3651#ifdef HAVE_FCHOWNAT
Ronald Oussoren41761932020-11-08 10:05:27 +01003652 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
3653 if (HAVE_FCHOWNAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10003654 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003655 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +01003656 } else {
3657 fchownat_unsupported = 1;
3658 }
3659 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003660#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003661 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003662 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003663
Ronald Oussoren41761932020-11-08 10:05:27 +01003664#ifdef HAVE_FCHOWNAT
3665 if (fchownat_unsupported) {
3666 /* This would be incorrect if the current platform
3667 * doesn't support lchown.
3668 */
3669 argument_unavailable_error(NULL, "dir_fd");
3670 return NULL;
3671 }
3672#endif
3673
Larry Hastings2f936352014-08-05 14:04:04 +10003674 if (result)
3675 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003676
Larry Hastings2f936352014-08-05 14:04:04 +10003677 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003678}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003679#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003680
Larry Hastings2f936352014-08-05 14:04:04 +10003681
Christian Heimes4e30a842007-11-30 22:12:06 +00003682#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003683/*[clinic input]
3684os.fchown
3685
3686 fd: int
3687 uid: uid_t
3688 gid: gid_t
3689
3690Change the owner and group id of the file specified by file descriptor.
3691
3692Equivalent to os.chown(fd, uid, gid).
3693
3694[clinic start generated code]*/
3695
Larry Hastings2f936352014-08-05 14:04:04 +10003696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003697os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3698/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003699{
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003701 int async_err = 0;
3702
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003703 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3704 return NULL;
3705 }
3706
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003707 do {
3708 Py_BEGIN_ALLOW_THREADS
3709 res = fchown(fd, uid, gid);
3710 Py_END_ALLOW_THREADS
3711 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3712 if (res != 0)
3713 return (!async_err) ? posix_error() : NULL;
3714
Victor Stinner8c62be82010-05-06 00:08:46 +00003715 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003716}
3717#endif /* HAVE_FCHOWN */
3718
Larry Hastings2f936352014-08-05 14:04:04 +10003719
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003720#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003721/*[clinic input]
3722os.lchown
3723
3724 path : path_t
3725 uid: uid_t
3726 gid: gid_t
3727
3728Change the owner and group id of path to the numeric uid and gid.
3729
3730This function will not follow symbolic links.
3731Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3732[clinic start generated code]*/
3733
Larry Hastings2f936352014-08-05 14:04:04 +10003734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003735os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3736/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003737{
Victor Stinner8c62be82010-05-06 00:08:46 +00003738 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003739 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3740 return NULL;
3741 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003742 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003743 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003744 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003745 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003746 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003747 }
Larry Hastings2f936352014-08-05 14:04:04 +10003748 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003749}
3750#endif /* HAVE_LCHOWN */
3751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003752
Barry Warsaw53699e91996-12-10 23:23:01 +00003753static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003754posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003755{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003756#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003757 wchar_t wbuf[MAXPATHLEN];
3758 wchar_t *wbuf2 = wbuf;
3759 DWORD len;
3760
3761 Py_BEGIN_ALLOW_THREADS
3762 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3763 /* If the buffer is large enough, len does not include the
3764 terminating \0. If the buffer is too small, len includes
3765 the space needed for the terminator. */
3766 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003767 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003768 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003769 }
Victor Stinner689830e2019-06-26 17:31:12 +02003770 else {
3771 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003772 }
Victor Stinner689830e2019-06-26 17:31:12 +02003773 if (wbuf2) {
3774 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 }
Victor Stinner689830e2019-06-26 17:31:12 +02003776 }
3777 Py_END_ALLOW_THREADS
3778
3779 if (!wbuf2) {
3780 PyErr_NoMemory();
3781 return NULL;
3782 }
3783 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003784 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003785 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003786 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003787 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003788
Victor Stinner689830e2019-06-26 17:31:12 +02003789 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3790 if (wbuf2 != wbuf) {
3791 PyMem_RawFree(wbuf2);
3792 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003793
Victor Stinner689830e2019-06-26 17:31:12 +02003794 if (use_bytes) {
3795 if (resobj == NULL) {
3796 return NULL;
3797 }
3798 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3799 }
3800
3801 return resobj;
3802#else
3803 const size_t chunk = 1024;
3804
3805 char *buf = NULL;
3806 char *cwd = NULL;
3807 size_t buflen = 0;
3808
Victor Stinner8c62be82010-05-06 00:08:46 +00003809 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003810 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003811 char *newbuf;
3812 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3813 buflen += chunk;
3814 newbuf = PyMem_RawRealloc(buf, buflen);
3815 }
3816 else {
3817 newbuf = NULL;
3818 }
3819 if (newbuf == NULL) {
3820 PyMem_RawFree(buf);
3821 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003822 break;
3823 }
Victor Stinner689830e2019-06-26 17:31:12 +02003824 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003825
Victor Stinner4403d7d2015-04-25 00:16:10 +02003826 cwd = getcwd(buf, buflen);
3827 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003828 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003829
Victor Stinner689830e2019-06-26 17:31:12 +02003830 if (buf == NULL) {
3831 return PyErr_NoMemory();
3832 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003833 if (cwd == NULL) {
3834 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003835 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003836 }
3837
Victor Stinner689830e2019-06-26 17:31:12 +02003838 PyObject *obj;
3839 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003840 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003841 }
3842 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003843 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003844 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003845 PyMem_RawFree(buf);
3846
3847 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003848#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003849}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003850
Larry Hastings2f936352014-08-05 14:04:04 +10003851
3852/*[clinic input]
3853os.getcwd
3854
3855Return a unicode string representing the current working directory.
3856[clinic start generated code]*/
3857
Larry Hastings2f936352014-08-05 14:04:04 +10003858static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003859os_getcwd_impl(PyObject *module)
3860/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003861{
3862 return posix_getcwd(0);
3863}
3864
Larry Hastings2f936352014-08-05 14:04:04 +10003865
3866/*[clinic input]
3867os.getcwdb
3868
3869Return a bytes string representing the current working directory.
3870[clinic start generated code]*/
3871
Larry Hastings2f936352014-08-05 14:04:04 +10003872static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003873os_getcwdb_impl(PyObject *module)
3874/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003875{
3876 return posix_getcwd(1);
3877}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003878
Larry Hastings2f936352014-08-05 14:04:04 +10003879
Larry Hastings9cf065c2012-06-22 16:30:09 -07003880#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3881#define HAVE_LINK 1
3882#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003883
Guido van Rossumb6775db1994-08-01 11:34:53 +00003884#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003885/*[clinic input]
3886
3887os.link
3888
3889 src : path_t
3890 dst : path_t
3891 *
3892 src_dir_fd : dir_fd = None
3893 dst_dir_fd : dir_fd = None
3894 follow_symlinks: bool = True
3895
3896Create a hard link to a file.
3897
3898If either src_dir_fd or dst_dir_fd is not None, it should be a file
3899 descriptor open to a directory, and the respective path string (src or dst)
3900 should be relative; the path will then be relative to that directory.
3901If follow_symlinks is False, and the last element of src is a symbolic
3902 link, link will create a link to the symbolic link itself instead of the
3903 file the link points to.
3904src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3905 platform. If they are unavailable, using them will raise a
3906 NotImplementedError.
3907[clinic start generated code]*/
3908
Larry Hastings2f936352014-08-05 14:04:04 +10003909static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003910os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003911 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003912/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003913{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003914#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003915 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003916#else
3917 int result;
3918#endif
Ronald Oussoren41761932020-11-08 10:05:27 +01003919#if defined(HAVE_LINKAT)
3920 int linkat_unavailable = 0;
3921#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003922
Larry Hastings9cf065c2012-06-22 16:30:09 -07003923#ifndef HAVE_LINKAT
3924 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3925 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003926 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003927 }
3928#endif
3929
Steve Dowercc16be82016-09-08 10:35:16 -07003930#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003931 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003932 PyErr_SetString(PyExc_NotImplementedError,
3933 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003934 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003935 }
Steve Dowercc16be82016-09-08 10:35:16 -07003936#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003937
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003938 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3939 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3940 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3941 return NULL;
3942 }
3943
Brian Curtin1b9df392010-11-24 20:24:31 +00003944#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003945 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003946 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003947 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003948
Larry Hastings2f936352014-08-05 14:04:04 +10003949 if (!result)
3950 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003951#else
3952 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003953#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003954 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3955 (dst_dir_fd != DEFAULT_DIR_FD) ||
Ronald Oussoren41761932020-11-08 10:05:27 +01003956 (!follow_symlinks)) {
3957
3958 if (HAVE_LINKAT_RUNTIME) {
3959
3960 result = linkat(src_dir_fd, src->narrow,
3961 dst_dir_fd, dst->narrow,
3962 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3963
3964 }
3965#ifdef __APPLE__
3966 else {
3967 if (src_dir_fd == DEFAULT_DIR_FD && dst_dir_fd == DEFAULT_DIR_FD) {
3968 /* See issue 41355: This matches the behaviour of !HAVE_LINKAT */
3969 result = link(src->narrow, dst->narrow);
3970 } else {
3971 linkat_unavailable = 1;
3972 }
3973 }
3974#endif
3975 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003976 else
Steve Dowercc16be82016-09-08 10:35:16 -07003977#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003978 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003979 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003980
Ronald Oussoren41761932020-11-08 10:05:27 +01003981#ifdef HAVE_LINKAT
3982 if (linkat_unavailable) {
3983 /* Either or both dir_fd arguments were specified */
3984 if (src_dir_fd != DEFAULT_DIR_FD) {
3985 argument_unavailable_error("link", "src_dir_fd");
3986 } else {
3987 argument_unavailable_error("link", "dst_dir_fd");
3988 }
3989 return NULL;
3990 }
3991#endif
3992
Larry Hastings2f936352014-08-05 14:04:04 +10003993 if (result)
3994 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003995#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003996
Larry Hastings2f936352014-08-05 14:04:04 +10003997 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003998}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999#endif
4000
Brian Curtin1b9df392010-11-24 20:24:31 +00004001
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004002#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00004003static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004004_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00004005{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004006 PyObject *v;
4007 HANDLE hFindFile = INVALID_HANDLE_VALUE;
4008 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07004009 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004010 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01004011 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004012 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004013
Steve Dowercc16be82016-09-08 10:35:16 -07004014 WIN32_FIND_DATAW wFileData;
4015 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004016
Steve Dowercc16be82016-09-08 10:35:16 -07004017 if (!path->wide) { /* Default arg: "." */
4018 po_wchars = L".";
4019 len = 1;
4020 } else {
4021 po_wchars = path->wide;
4022 len = wcslen(path->wide);
4023 }
4024 /* The +5 is so we can append "\\*.*\0" */
4025 wnamebuf = PyMem_New(wchar_t, len + 5);
4026 if (!wnamebuf) {
4027 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07004028 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004029 }
Steve Dowercc16be82016-09-08 10:35:16 -07004030 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00004031 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07004032 wchar_t wch = wnamebuf[len-1];
4033 if (wch != SEP && wch != ALTSEP && wch != L':')
4034 wnamebuf[len++] = SEP;
4035 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00004036 }
Steve Dowercc16be82016-09-08 10:35:16 -07004037 if ((list = PyList_New(0)) == NULL) {
4038 goto exit;
4039 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00004040 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004041 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00004042 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004043 if (hFindFile == INVALID_HANDLE_VALUE) {
4044 int error = GetLastError();
4045 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004046 goto exit;
4047 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004048 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004049 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004050 }
4051 do {
4052 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07004053 if (wcscmp(wFileData.cFileName, L".") != 0 &&
4054 wcscmp(wFileData.cFileName, L"..") != 0) {
4055 v = PyUnicode_FromWideChar(wFileData.cFileName,
4056 wcslen(wFileData.cFileName));
4057 if (path->narrow && v) {
4058 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
4059 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004060 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004061 Py_DECREF(list);
4062 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004063 break;
4064 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004065 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004066 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004067 Py_DECREF(list);
4068 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004069 break;
4070 }
4071 Py_DECREF(v);
4072 }
4073 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004074 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00004075 Py_END_ALLOW_THREADS
4076 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4077 it got to the end of the directory. */
4078 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004079 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004080 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004082 }
4083 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004084
Larry Hastings9cf065c2012-06-22 16:30:09 -07004085exit:
4086 if (hFindFile != INVALID_HANDLE_VALUE) {
4087 if (FindClose(hFindFile) == FALSE) {
4088 if (list != NULL) {
4089 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004090 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004091 }
4092 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004093 }
Victor Stinnerb6404912013-07-07 16:21:41 +02004094 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004095
Larry Hastings9cf065c2012-06-22 16:30:09 -07004096 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004097} /* end of _listdir_windows_no_opendir */
4098
4099#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
4100
4101static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004102_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004103{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004104 PyObject *v;
4105 DIR *dirp = NULL;
4106 struct dirent *ep;
4107 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004108#ifdef HAVE_FDOPENDIR
4109 int fd = -1;
4110#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004111
Victor Stinner8c62be82010-05-06 00:08:46 +00004112 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07004114 if (path->fd != -1) {
Ronald Oussoren41761932020-11-08 10:05:27 +01004115 if (HAVE_FDOPENDIR_RUNTIME) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004116 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02004117 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01004118 if (fd == -1)
4119 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004120
Larry Hastingsfdaea062012-06-25 04:42:23 -07004121 return_str = 1;
4122
Larry Hastings9cf065c2012-06-22 16:30:09 -07004123 Py_BEGIN_ALLOW_THREADS
4124 dirp = fdopendir(fd);
4125 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01004126 } else {
4127 PyErr_SetString(PyExc_TypeError,
4128 "listdir: path should be string, bytes, os.PathLike or None, not int");
4129 return NULL;
4130 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004131 }
4132 else
4133#endif
4134 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004135 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07004136 if (path->narrow) {
4137 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03004138 /* only return bytes if they specified a bytes-like object */
4139 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07004140 }
4141 else {
4142 name = ".";
4143 return_str = 1;
4144 }
4145
Larry Hastings9cf065c2012-06-22 16:30:09 -07004146 Py_BEGIN_ALLOW_THREADS
4147 dirp = opendir(name);
4148 Py_END_ALLOW_THREADS
4149 }
4150
4151 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07004152 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004153#ifdef HAVE_FDOPENDIR
4154 if (fd != -1) {
4155 Py_BEGIN_ALLOW_THREADS
4156 close(fd);
4157 Py_END_ALLOW_THREADS
4158 }
4159#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004160 goto exit;
4161 }
4162 if ((list = PyList_New(0)) == NULL) {
4163 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 }
4165 for (;;) {
4166 errno = 0;
4167 Py_BEGIN_ALLOW_THREADS
4168 ep = readdir(dirp);
4169 Py_END_ALLOW_THREADS
4170 if (ep == NULL) {
4171 if (errno == 0) {
4172 break;
4173 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004174 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004175 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004176 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004177 }
4178 }
4179 if (ep->d_name[0] == '.' &&
4180 (NAMLEN(ep) == 1 ||
4181 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
4182 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07004183 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00004184 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
4185 else
4186 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00004187 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004188 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004189 break;
4190 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004191 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004193 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004194 break;
4195 }
4196 Py_DECREF(v);
4197 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00004198
Larry Hastings9cf065c2012-06-22 16:30:09 -07004199exit:
4200 if (dirp != NULL) {
4201 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004202#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07004203 if (fd > -1)
4204 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004205#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004206 closedir(dirp);
4207 Py_END_ALLOW_THREADS
4208 }
4209
Larry Hastings9cf065c2012-06-22 16:30:09 -07004210 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004211} /* end of _posix_listdir */
4212#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004213
Larry Hastings2f936352014-08-05 14:04:04 +10004214
4215/*[clinic input]
4216os.listdir
4217
4218 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
4219
4220Return a list containing the names of the files in the directory.
4221
BNMetricsb9427072018-11-02 15:20:19 +00004222path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10004223 the filenames returned will also be bytes; in all other circumstances
4224 the filenames returned will be str.
4225If path is None, uses the path='.'.
4226On some platforms, path may also be specified as an open file descriptor;\
4227 the file descriptor must refer to a directory.
4228 If this functionality is unavailable, using it raises NotImplementedError.
4229
4230The list is in arbitrary order. It does not include the special
4231entries '.' and '..' even if they are present in the directory.
4232
4233
4234[clinic start generated code]*/
4235
Larry Hastings2f936352014-08-05 14:04:04 +10004236static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004237os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00004238/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004239{
Steve Dower60419a72019-06-24 08:42:54 -07004240 if (PySys_Audit("os.listdir", "O",
4241 path->object ? path->object : Py_None) < 0) {
4242 return NULL;
4243 }
Larry Hastings2f936352014-08-05 14:04:04 +10004244#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4245 return _listdir_windows_no_opendir(path, NULL);
4246#else
4247 return _posix_listdir(path, NULL);
4248#endif
4249}
4250
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004251#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00004252/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004253/*[clinic input]
4254os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02004255
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004256 path: path_t
4257 /
4258
4259[clinic start generated code]*/
4260
4261static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004262os__getfullpathname_impl(PyObject *module, path_t *path)
4263/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004264{
Victor Stinner3939c322019-06-25 15:02:43 +02004265 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004266
Victor Stinner3939c322019-06-25 15:02:43 +02004267 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
4268 if (_Py_abspath(path->wide, &abspath) < 0) {
4269 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00004270 }
Victor Stinner3939c322019-06-25 15:02:43 +02004271 if (abspath == NULL) {
4272 return PyErr_NoMemory();
4273 }
4274
4275 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
4276 PyMem_RawFree(abspath);
4277 if (str == NULL) {
4278 return NULL;
4279 }
4280 if (path->narrow) {
4281 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
4282 }
4283 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10004284}
Brian Curtind40e6f72010-07-08 21:39:08 +00004285
Brian Curtind25aef52011-06-13 15:16:04 -05004286
Larry Hastings2f936352014-08-05 14:04:04 +10004287/*[clinic input]
4288os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004289
Steve Dower23ad6d02018-02-22 10:39:10 -08004290 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004291 /
4292
4293A helper function for samepath on windows.
4294[clinic start generated code]*/
4295
Larry Hastings2f936352014-08-05 14:04:04 +10004296static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004297os__getfinalpathname_impl(PyObject *module, path_t *path)
4298/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004299{
4300 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004301 wchar_t buf[MAXPATHLEN], *target_path = buf;
4302 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004303 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004304 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004305
Steve Dower23ad6d02018-02-22 10:39:10 -08004306 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004307 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004308 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004309 0, /* desired access */
4310 0, /* share mode */
4311 NULL, /* security attributes */
4312 OPEN_EXISTING,
4313 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4314 FILE_FLAG_BACKUP_SEMANTICS,
4315 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004316 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004317
Steve Dower23ad6d02018-02-22 10:39:10 -08004318 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004319 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004320 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004321
4322 /* We have a good handle to the target, use it to determine the
4323 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004324 while (1) {
4325 Py_BEGIN_ALLOW_THREADS
4326 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4327 buf_size, VOLUME_NAME_DOS);
4328 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004329
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004330 if (!result_length) {
4331 result = win32_error_object("GetFinalPathNameByHandleW",
4332 path->object);
4333 goto cleanup;
4334 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004335
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004336 if (result_length < buf_size) {
4337 break;
4338 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004339
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004340 wchar_t *tmp;
4341 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4342 result_length * sizeof(*tmp));
4343 if (!tmp) {
4344 result = PyErr_NoMemory();
4345 goto cleanup;
4346 }
4347
4348 buf_size = result_length;
4349 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004350 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004351
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004352 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004353 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004354 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004355 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004356
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004357cleanup:
4358 if (target_path != buf) {
4359 PyMem_Free(target_path);
4360 }
4361 CloseHandle(hFile);
4362 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004363}
Brian Curtin62857742010-09-06 17:07:27 +00004364
Tim Golden6b528062013-08-01 12:44:00 +01004365
Larry Hastings2f936352014-08-05 14:04:04 +10004366/*[clinic input]
4367os._getvolumepathname
4368
Steve Dower23ad6d02018-02-22 10:39:10 -08004369 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004370
4371A helper function for ismount on Win32.
4372[clinic start generated code]*/
4373
Larry Hastings2f936352014-08-05 14:04:04 +10004374static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004375os__getvolumepathname_impl(PyObject *module, path_t *path)
4376/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004377{
4378 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004379 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004380 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004381 BOOL ret;
4382
Tim Golden6b528062013-08-01 12:44:00 +01004383 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004384 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004385
Victor Stinner850a18e2017-10-24 16:53:32 -07004386 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004387 PyErr_SetString(PyExc_OverflowError, "path too long");
4388 return NULL;
4389 }
4390
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004391 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004392 if (mountpath == NULL)
4393 return PyErr_NoMemory();
4394
4395 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004396 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004397 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004398 Py_END_ALLOW_THREADS
4399
4400 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004401 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004402 goto exit;
4403 }
4404 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004405 if (path->narrow)
4406 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004407
4408exit:
4409 PyMem_Free(mountpath);
4410 return result;
4411}
Tim Golden6b528062013-08-01 12:44:00 +01004412
Steve Dower04732ca2021-04-07 01:02:07 +01004413
4414/*[clinic input]
4415os._path_splitroot
4416
4417 path: path_t
4418
4419Removes everything after the root on Win32.
4420[clinic start generated code]*/
4421
4422static PyObject *
4423os__path_splitroot_impl(PyObject *module, path_t *path)
4424/*[clinic end generated code: output=ab7f1a88b654581c input=dc93b1d3984cffb6]*/
4425{
4426 wchar_t *buffer;
4427 wchar_t *end;
4428 PyObject *result = NULL;
4429 HRESULT ret;
4430
4431 buffer = (wchar_t*)PyMem_Malloc(sizeof(wchar_t) * (wcslen(path->wide) + 1));
4432 if (!buffer) {
4433 return NULL;
4434 }
4435 wcscpy(buffer, path->wide);
4436 for (wchar_t *p = wcschr(buffer, L'/'); p; p = wcschr(p, L'/')) {
4437 *p = L'\\';
4438 }
4439
4440 Py_BEGIN_ALLOW_THREADS
4441 ret = PathCchSkipRoot(buffer, &end);
4442 Py_END_ALLOW_THREADS
4443 if (FAILED(ret)) {
4444 result = Py_BuildValue("sO", "", path->object);
4445 } else if (end != buffer) {
4446 size_t rootLen = (size_t)(end - buffer);
4447 result = Py_BuildValue("NN",
4448 PyUnicode_FromWideChar(path->wide, rootLen),
4449 PyUnicode_FromWideChar(path->wide + rootLen, -1)
4450 );
4451 } else {
4452 result = Py_BuildValue("Os", path->object, "");
4453 }
4454 PyMem_Free(buffer);
4455
4456 return result;
4457}
4458
4459
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004460#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004461
Larry Hastings2f936352014-08-05 14:04:04 +10004462
4463/*[clinic input]
4464os.mkdir
4465
4466 path : path_t
4467
4468 mode: int = 0o777
4469
4470 *
4471
4472 dir_fd : dir_fd(requires='mkdirat') = None
4473
4474# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4475
4476Create a directory.
4477
4478If dir_fd is not None, it should be a file descriptor open to a directory,
4479 and path should be relative; path will then be relative to that directory.
4480dir_fd may not be implemented on your platform.
4481 If it is unavailable, using it will raise a NotImplementedError.
4482
4483The mode argument is ignored on Windows.
4484[clinic start generated code]*/
4485
Larry Hastings2f936352014-08-05 14:04:04 +10004486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004487os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4488/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004489{
4490 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004491#ifdef HAVE_MKDIRAT
4492 int mkdirat_unavailable = 0;
4493#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004494
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004495 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4496 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4497 return NULL;
4498 }
4499
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004500#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004501 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004502 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004503 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004504
Larry Hastings2f936352014-08-05 14:04:04 +10004505 if (!result)
4506 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004507#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004508 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004509#if HAVE_MKDIRAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004510 if (dir_fd != DEFAULT_DIR_FD) {
4511 if (HAVE_MKDIRAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004512 result = mkdirat(dir_fd, path->narrow, mode);
Ronald Oussoren41761932020-11-08 10:05:27 +01004513
4514 } else {
4515 mkdirat_unavailable = 1;
4516 }
4517 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004519#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004520 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004521#else
Larry Hastings2f936352014-08-05 14:04:04 +10004522 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004523#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004524 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01004525
4526#if HAVE_MKDIRAT
4527 if (mkdirat_unavailable) {
4528 argument_unavailable_error(NULL, "dir_fd");
4529 return NULL;
4530 }
4531#endif
4532
Larry Hastings2f936352014-08-05 14:04:04 +10004533 if (result < 0)
4534 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004535#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004536 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004537}
4538
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004539
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004540/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4541#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004542#include <sys/resource.h>
4543#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004544
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004545
4546#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004547/*[clinic input]
4548os.nice
4549
4550 increment: int
4551 /
4552
4553Add increment to the priority of process and return the new priority.
4554[clinic start generated code]*/
4555
Larry Hastings2f936352014-08-05 14:04:04 +10004556static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004557os_nice_impl(PyObject *module, int increment)
4558/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004559{
4560 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004561
Victor Stinner8c62be82010-05-06 00:08:46 +00004562 /* There are two flavours of 'nice': one that returns the new
4563 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004564 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004565 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004566
Victor Stinner8c62be82010-05-06 00:08:46 +00004567 If we are of the nice family that returns the new priority, we
4568 need to clear errno before the call, and check if errno is filled
4569 before calling posix_error() on a returnvalue of -1, because the
4570 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004571
Victor Stinner8c62be82010-05-06 00:08:46 +00004572 errno = 0;
4573 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004574#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004575 if (value == 0)
4576 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004577#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004578 if (value == -1 && errno != 0)
4579 /* either nice() or getpriority() returned an error */
4580 return posix_error();
4581 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004582}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004583#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004584
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004585
4586#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004587/*[clinic input]
4588os.getpriority
4589
4590 which: int
4591 who: int
4592
4593Return program scheduling priority.
4594[clinic start generated code]*/
4595
Larry Hastings2f936352014-08-05 14:04:04 +10004596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004597os_getpriority_impl(PyObject *module, int which, int who)
4598/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004599{
4600 int retval;
4601
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004602 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004603 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004604 if (errno != 0)
4605 return posix_error();
4606 return PyLong_FromLong((long)retval);
4607}
4608#endif /* HAVE_GETPRIORITY */
4609
4610
4611#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004612/*[clinic input]
4613os.setpriority
4614
4615 which: int
4616 who: int
4617 priority: int
4618
4619Set program scheduling priority.
4620[clinic start generated code]*/
4621
Larry Hastings2f936352014-08-05 14:04:04 +10004622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004623os_setpriority_impl(PyObject *module, int which, int who, int priority)
4624/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004625{
4626 int retval;
4627
4628 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004629 if (retval == -1)
4630 return posix_error();
4631 Py_RETURN_NONE;
4632}
4633#endif /* HAVE_SETPRIORITY */
4634
4635
Barry Warsaw53699e91996-12-10 23:23:01 +00004636static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004637internal_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 +00004638{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004639 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004640 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641
Ronald Oussoren41761932020-11-08 10:05:27 +01004642#ifdef HAVE_RENAMEAT
4643 int renameat_unavailable = 0;
4644#endif
4645
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004646#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004647 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004648 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004649#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004650 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004651#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652
Larry Hastings9cf065c2012-06-22 16:30:09 -07004653 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4654 (dst_dir_fd != DEFAULT_DIR_FD);
4655#ifndef HAVE_RENAMEAT
4656 if (dir_fd_specified) {
4657 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004658 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004659 }
4660#endif
4661
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004662 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4663 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4664 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4665 return NULL;
4666 }
4667
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668#ifdef MS_WINDOWS
4669 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004670 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671 Py_END_ALLOW_THREADS
4672
Larry Hastings2f936352014-08-05 14:04:04 +10004673 if (!result)
4674 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675
4676#else
Steve Dowercc16be82016-09-08 10:35:16 -07004677 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4678 PyErr_Format(PyExc_ValueError,
4679 "%s: src and dst must be the same type", function_name);
4680 return NULL;
4681 }
4682
Larry Hastings9cf065c2012-06-22 16:30:09 -07004683 Py_BEGIN_ALLOW_THREADS
4684#ifdef HAVE_RENAMEAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004685 if (dir_fd_specified) {
4686 if (HAVE_RENAMEAT_RUNTIME) {
4687 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
4688 } else {
4689 renameat_unavailable = 1;
4690 }
4691 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004693 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004694 Py_END_ALLOW_THREADS
4695
Ronald Oussoren41761932020-11-08 10:05:27 +01004696
4697#ifdef HAVE_RENAMEAT
4698 if (renameat_unavailable) {
4699 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4700 return NULL;
4701 }
4702#endif
4703
Larry Hastings2f936352014-08-05 14:04:04 +10004704 if (result)
4705 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004707 Py_RETURN_NONE;
4708}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709
Larry Hastings2f936352014-08-05 14:04:04 +10004710
4711/*[clinic input]
4712os.rename
4713
4714 src : path_t
4715 dst : path_t
4716 *
4717 src_dir_fd : dir_fd = None
4718 dst_dir_fd : dir_fd = None
4719
4720Rename a file or directory.
4721
4722If either src_dir_fd or dst_dir_fd is not None, it should be a file
4723 descriptor open to a directory, and the respective path string (src or dst)
4724 should be relative; the path will then be relative to that directory.
4725src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4726 If they are unavailable, using them will raise a NotImplementedError.
4727[clinic start generated code]*/
4728
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004729static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004730os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004731 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004732/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004733{
Larry Hastings2f936352014-08-05 14:04:04 +10004734 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004735}
4736
Larry Hastings2f936352014-08-05 14:04:04 +10004737
4738/*[clinic input]
4739os.replace = os.rename
4740
4741Rename a file or directory, overwriting the destination.
4742
4743If either src_dir_fd or dst_dir_fd is not None, it should be a file
4744 descriptor open to a directory, and the respective path string (src or dst)
4745 should be relative; the path will then be relative to that directory.
4746src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004747 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004748[clinic start generated code]*/
4749
Larry Hastings2f936352014-08-05 14:04:04 +10004750static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004751os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4752 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004753/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004754{
4755 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4756}
4757
4758
4759/*[clinic input]
4760os.rmdir
4761
4762 path: path_t
4763 *
4764 dir_fd: dir_fd(requires='unlinkat') = None
4765
4766Remove a directory.
4767
4768If dir_fd is not None, it should be a file descriptor open to a directory,
4769 and path should be relative; path will then be relative to that directory.
4770dir_fd may not be implemented on your platform.
4771 If it is unavailable, using it will raise a NotImplementedError.
4772[clinic start generated code]*/
4773
Larry Hastings2f936352014-08-05 14:04:04 +10004774static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004775os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4776/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004777{
4778 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004779#ifdef HAVE_UNLINKAT
4780 int unlinkat_unavailable = 0;
4781#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004782
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004783 if (PySys_Audit("os.rmdir", "Oi", path->object,
4784 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4785 return NULL;
4786 }
4787
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004788 Py_BEGIN_ALLOW_THREADS
4789#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004790 /* Windows, success=1, UNIX, success=0 */
4791 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004792#else
4793#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004794 if (dir_fd != DEFAULT_DIR_FD) {
4795 if (HAVE_UNLINKAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004796 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Ronald Oussoren41761932020-11-08 10:05:27 +01004797 } else {
4798 unlinkat_unavailable = 1;
4799 result = -1;
4800 }
4801 } else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004802#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004803 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004804#endif
4805 Py_END_ALLOW_THREADS
4806
Ronald Oussoren41761932020-11-08 10:05:27 +01004807#ifdef HAVE_UNLINKAT
4808 if (unlinkat_unavailable) {
4809 argument_unavailable_error("rmdir", "dir_fd");
4810 return NULL;
4811 }
4812#endif
4813
Larry Hastings2f936352014-08-05 14:04:04 +10004814 if (result)
4815 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004816
Larry Hastings2f936352014-08-05 14:04:04 +10004817 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004818}
4819
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004820
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004821#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004822#ifdef MS_WINDOWS
4823/*[clinic input]
4824os.system -> long
4825
4826 command: Py_UNICODE
4827
4828Execute the command in a subshell.
4829[clinic start generated code]*/
4830
Larry Hastings2f936352014-08-05 14:04:04 +10004831static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004832os_system_impl(PyObject *module, const Py_UNICODE *command)
4833/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004834{
4835 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004836
Steve Dowerfbe3c762019-10-18 00:52:15 -07004837 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004838 return -1;
4839 }
4840
Victor Stinner8c62be82010-05-06 00:08:46 +00004841 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004842 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004843 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004844 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004845 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004846 return result;
4847}
4848#else /* MS_WINDOWS */
4849/*[clinic input]
4850os.system -> long
4851
4852 command: FSConverter
4853
4854Execute the command in a subshell.
4855[clinic start generated code]*/
4856
Larry Hastings2f936352014-08-05 14:04:04 +10004857static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004858os_system_impl(PyObject *module, PyObject *command)
4859/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004860{
4861 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004862 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004863
Steve Dowerfbe3c762019-10-18 00:52:15 -07004864 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004865 return -1;
4866 }
4867
Larry Hastings2f936352014-08-05 14:04:04 +10004868 Py_BEGIN_ALLOW_THREADS
4869 result = system(bytes);
4870 Py_END_ALLOW_THREADS
4871 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004872}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004873#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004874#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004875
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004876
Larry Hastings2f936352014-08-05 14:04:04 +10004877/*[clinic input]
4878os.umask
4879
4880 mask: int
4881 /
4882
4883Set the current numeric umask and return the previous umask.
4884[clinic start generated code]*/
4885
Larry Hastings2f936352014-08-05 14:04:04 +10004886static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004887os_umask_impl(PyObject *module, int mask)
4888/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004889{
4890 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004891 if (i < 0)
4892 return posix_error();
4893 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004894}
4895
Brian Curtind40e6f72010-07-08 21:39:08 +00004896#ifdef MS_WINDOWS
4897
4898/* override the default DeleteFileW behavior so that directory
4899symlinks can be removed with this function, the same as with
4900Unix symlinks */
4901BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4902{
4903 WIN32_FILE_ATTRIBUTE_DATA info;
4904 WIN32_FIND_DATAW find_data;
4905 HANDLE find_data_handle;
4906 int is_directory = 0;
4907 int is_link = 0;
4908
4909 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4910 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004911
Brian Curtind40e6f72010-07-08 21:39:08 +00004912 /* Get WIN32_FIND_DATA structure for the path to determine if
4913 it is a symlink */
4914 if(is_directory &&
4915 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4916 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4917
4918 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004919 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4920 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4921 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4922 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004923 FindClose(find_data_handle);
4924 }
4925 }
4926 }
4927
4928 if (is_directory && is_link)
4929 return RemoveDirectoryW(lpFileName);
4930
4931 return DeleteFileW(lpFileName);
4932}
4933#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004934
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004935
Larry Hastings2f936352014-08-05 14:04:04 +10004936/*[clinic input]
4937os.unlink
4938
4939 path: path_t
4940 *
4941 dir_fd: dir_fd(requires='unlinkat')=None
4942
4943Remove a file (same as remove()).
4944
4945If dir_fd is not None, it should be a file descriptor open to a directory,
4946 and path should be relative; path will then be relative to that directory.
4947dir_fd may not be implemented on your platform.
4948 If it is unavailable, using it will raise a NotImplementedError.
4949
4950[clinic start generated code]*/
4951
Larry Hastings2f936352014-08-05 14:04:04 +10004952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004953os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4954/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004955{
4956 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004957#ifdef HAVE_UNLINKAT
4958 int unlinkat_unavailable = 0;
4959#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004960
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004961 if (PySys_Audit("os.remove", "Oi", path->object,
4962 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4963 return NULL;
4964 }
4965
Larry Hastings9cf065c2012-06-22 16:30:09 -07004966 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004967 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004969 /* Windows, success=1, UNIX, success=0 */
4970 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004971#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004972#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004973 if (dir_fd != DEFAULT_DIR_FD) {
4974 if (HAVE_UNLINKAT_RUNTIME) {
4975
Larry Hastings2f936352014-08-05 14:04:04 +10004976 result = unlinkat(dir_fd, path->narrow, 0);
Ronald Oussoren41761932020-11-08 10:05:27 +01004977 } else {
4978 unlinkat_unavailable = 1;
4979 }
4980 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004981#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004982 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004983#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004984 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985 Py_END_ALLOW_THREADS
4986
Ronald Oussoren41761932020-11-08 10:05:27 +01004987#ifdef HAVE_UNLINKAT
4988 if (unlinkat_unavailable) {
4989 argument_unavailable_error(NULL, "dir_fd");
4990 return NULL;
4991 }
4992#endif
4993
Larry Hastings2f936352014-08-05 14:04:04 +10004994 if (result)
4995 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004996
Larry Hastings2f936352014-08-05 14:04:04 +10004997 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004998}
4999
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005000
Larry Hastings2f936352014-08-05 14:04:04 +10005001/*[clinic input]
5002os.remove = os.unlink
5003
5004Remove a file (same as unlink()).
5005
5006If dir_fd is not None, it should be a file descriptor open to a directory,
5007 and path should be relative; path will then be relative to that directory.
5008dir_fd may not be implemented on your platform.
5009 If it is unavailable, using it will raise a NotImplementedError.
5010[clinic start generated code]*/
5011
Larry Hastings2f936352014-08-05 14:04:04 +10005012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005013os_remove_impl(PyObject *module, path_t *path, int dir_fd)
5014/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005015{
5016 return os_unlink_impl(module, path, dir_fd);
5017}
5018
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005019
Larry Hastings605a62d2012-06-24 04:33:36 -07005020static PyStructSequence_Field uname_result_fields[] = {
5021 {"sysname", "operating system name"},
5022 {"nodename", "name of machine on network (implementation-defined)"},
5023 {"release", "operating system release"},
5024 {"version", "operating system version"},
5025 {"machine", "hardware identifier"},
5026 {NULL}
5027};
5028
5029PyDoc_STRVAR(uname_result__doc__,
5030"uname_result: Result from os.uname().\n\n\
5031This object may be accessed either as a tuple of\n\
5032 (sysname, nodename, release, version, machine),\n\
5033or via the attributes sysname, nodename, release, version, and machine.\n\
5034\n\
5035See os.uname for more information.");
5036
5037static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08005038 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07005039 uname_result__doc__, /* doc */
5040 uname_result_fields,
5041 5
5042};
5043
Larry Hastings605a62d2012-06-24 04:33:36 -07005044#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10005045/*[clinic input]
5046os.uname
5047
5048Return an object identifying the current operating system.
5049
5050The object behaves like a named tuple with the following fields:
5051 (sysname, nodename, release, version, machine)
5052
5053[clinic start generated code]*/
5054
Larry Hastings2f936352014-08-05 14:04:04 +10005055static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005056os_uname_impl(PyObject *module)
5057/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00005058{
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 struct utsname u;
5060 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07005061 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00005062
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 Py_BEGIN_ALLOW_THREADS
5064 res = uname(&u);
5065 Py_END_ALLOW_THREADS
5066 if (res < 0)
5067 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07005068
Hai Shif707d942020-03-16 21:15:01 +08005069 PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08005070 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07005071 if (value == NULL)
5072 return NULL;
5073
5074#define SET(i, field) \
5075 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02005076 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07005077 if (!o) { \
5078 Py_DECREF(value); \
5079 return NULL; \
5080 } \
5081 PyStructSequence_SET_ITEM(value, i, o); \
5082 } \
5083
5084 SET(0, u.sysname);
5085 SET(1, u.nodename);
5086 SET(2, u.release);
5087 SET(3, u.version);
5088 SET(4, u.machine);
5089
5090#undef SET
5091
5092 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00005093}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005094#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005095
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005096
Larry Hastings9cf065c2012-06-22 16:30:09 -07005097
5098typedef struct {
5099 int now;
5100 time_t atime_s;
5101 long atime_ns;
5102 time_t mtime_s;
5103 long mtime_ns;
5104} utime_t;
5105
5106/*
Victor Stinner484df002014-10-09 13:52:31 +02005107 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07005108 * they also intentionally leak the declaration of a pointer named "time"
5109 */
5110#define UTIME_TO_TIMESPEC \
5111 struct timespec ts[2]; \
5112 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005113 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005114 time = NULL; \
5115 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005116 ts[0].tv_sec = ut->atime_s; \
5117 ts[0].tv_nsec = ut->atime_ns; \
5118 ts[1].tv_sec = ut->mtime_s; \
5119 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005120 time = ts; \
5121 } \
5122
5123#define UTIME_TO_TIMEVAL \
5124 struct timeval tv[2]; \
5125 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005126 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005127 time = NULL; \
5128 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005129 tv[0].tv_sec = ut->atime_s; \
5130 tv[0].tv_usec = ut->atime_ns / 1000; \
5131 tv[1].tv_sec = ut->mtime_s; \
5132 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005133 time = tv; \
5134 } \
5135
5136#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005137 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005138 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005139 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005140 time = NULL; \
5141 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005142 u.actime = ut->atime_s; \
5143 u.modtime = ut->mtime_s; \
5144 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005145 }
5146
5147#define UTIME_TO_TIME_T \
5148 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005149 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005150 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005151 time = NULL; \
5152 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005153 timet[0] = ut->atime_s; \
5154 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005155 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005156 } \
5157
5158
Victor Stinner528a9ab2015-09-03 21:30:26 +02005159#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005160
5161static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005162utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005163{
Ronald Oussoren41761932020-11-08 10:05:27 +01005164#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5165 if (HAVE_UTIMENSAT_RUNTIME) {
5166 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5167 UTIME_TO_TIMESPEC;
5168 return utimensat(dir_fd, path, time, flags);
5169 } else {
5170 errno = ENOSYS;
5171 return -1;
5172 }
5173#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005174 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5175 UTIME_TO_TIMESPEC;
5176 return utimensat(dir_fd, path, time, flags);
5177#elif defined(HAVE_FUTIMESAT)
5178 UTIME_TO_TIMEVAL;
5179 /*
5180 * follow_symlinks will never be false here;
5181 * we only allow !follow_symlinks and dir_fd together
5182 * if we have utimensat()
5183 */
5184 assert(follow_symlinks);
5185 return futimesat(dir_fd, path, time);
5186#endif
5187}
5188
Larry Hastings2f936352014-08-05 14:04:04 +10005189 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
5190#else
5191 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07005192#endif
5193
Victor Stinner528a9ab2015-09-03 21:30:26 +02005194#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005195
5196static int
Victor Stinner484df002014-10-09 13:52:31 +02005197utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005198{
5199#ifdef HAVE_FUTIMENS
Ronald Oussoren41761932020-11-08 10:05:27 +01005200
5201 if (HAVE_FUTIMENS_RUNTIME) {
5202
Larry Hastings9cf065c2012-06-22 16:30:09 -07005203 UTIME_TO_TIMESPEC;
5204 return futimens(fd, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005205
5206 } else
5207#ifndef HAVE_FUTIMES
5208 {
5209 /* Not sure if this can happen */
5210 PyErr_SetString(
5211 PyExc_RuntimeError,
5212 "neither futimens nor futimes are supported"
5213 " on this system");
5214 return -1;
5215 }
5216#endif
5217
5218#endif
5219#ifdef HAVE_FUTIMES
5220 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005221 UTIME_TO_TIMEVAL;
5222 return futimes(fd, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005223 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005224#endif
5225}
5226
Larry Hastings2f936352014-08-05 14:04:04 +10005227 #define PATH_UTIME_HAVE_FD 1
5228#else
5229 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07005230#endif
5231
Victor Stinner5ebae872015-09-22 01:29:33 +02005232#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
5233# define UTIME_HAVE_NOFOLLOW_SYMLINKS
5234#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005235
Victor Stinner4552ced2015-09-21 22:37:15 +02005236#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005237
5238static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005239utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005240{
5241#ifdef HAVE_UTIMENSAT
Ronald Oussoren41761932020-11-08 10:05:27 +01005242 if (HAVE_UTIMENSAT_RUNTIME) {
5243 UTIME_TO_TIMESPEC;
5244 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
5245 } else
5246#ifndef HAVE_LUTIMES
5247 {
5248 /* Not sure if this can happen */
5249 PyErr_SetString(
5250 PyExc_RuntimeError,
5251 "neither utimensat nor lutimes are supported"
5252 " on this system");
5253 return -1;
5254 }
5255#endif
5256#endif
5257
5258#ifdef HAVE_LUTIMES
5259 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005260 UTIME_TO_TIMEVAL;
5261 return lutimes(path, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005262 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005263#endif
5264}
5265
5266#endif
5267
5268#ifndef MS_WINDOWS
5269
5270static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005271utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005272{
Ronald Oussoren41761932020-11-08 10:05:27 +01005273#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5274 if (HAVE_UTIMENSAT_RUNTIME) {
5275 UTIME_TO_TIMESPEC;
5276 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5277 } else {
5278 UTIME_TO_TIMEVAL;
5279 return utimes(path, time);
5280 }
5281#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005282 UTIME_TO_TIMESPEC;
5283 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5284#elif defined(HAVE_UTIMES)
5285 UTIME_TO_TIMEVAL;
5286 return utimes(path, time);
5287#elif defined(HAVE_UTIME_H)
5288 UTIME_TO_UTIMBUF;
5289 return utime(path, time);
5290#else
5291 UTIME_TO_TIME_T;
5292 return utime(path, time);
5293#endif
5294}
5295
5296#endif
5297
Larry Hastings76ad59b2012-05-03 00:30:07 -07005298static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005299split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
Larry Hastings76ad59b2012-05-03 00:30:07 -07005300{
5301 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04005302 PyObject *divmod;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005303 divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07005304 if (!divmod)
5305 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005306 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
5307 PyErr_Format(PyExc_TypeError,
5308 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08005309 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005310 goto exit;
5311 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005312 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
5313 if ((*s == -1) && PyErr_Occurred())
5314 goto exit;
5315 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04005316 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07005317 goto exit;
5318
5319 result = 1;
5320exit:
5321 Py_XDECREF(divmod);
5322 return result;
5323}
5324
Larry Hastings2f936352014-08-05 14:04:04 +10005325
5326/*[clinic input]
5327os.utime
5328
5329 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005330 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10005331 *
5332 ns: object = NULL
5333 dir_fd: dir_fd(requires='futimensat') = None
5334 follow_symlinks: bool=True
5335
Martin Panter0ff89092015-09-09 01:56:53 +00005336# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10005337
5338Set the access and modified time of path.
5339
5340path may always be specified as a string.
5341On some platforms, path may also be specified as an open file descriptor.
5342 If this functionality is unavailable, using it raises an exception.
5343
5344If times is not None, it must be a tuple (atime, mtime);
5345 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005346If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10005347 atime_ns and mtime_ns should be expressed as integer nanoseconds
5348 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005349If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10005350Specifying tuples for both times and ns is an error.
5351
5352If dir_fd is not None, it should be a file descriptor open to a directory,
5353 and path should be relative; path will then be relative to that directory.
5354If follow_symlinks is False, and the last element of the path is a symbolic
5355 link, utime will modify the symbolic link itself instead of the file the
5356 link points to.
5357It is an error to use dir_fd or follow_symlinks when specifying path
5358 as an open file descriptor.
5359dir_fd and follow_symlinks may not be available on your platform.
5360 If they are unavailable, using them will raise a NotImplementedError.
5361
5362[clinic start generated code]*/
5363
Larry Hastings2f936352014-08-05 14:04:04 +10005364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005365os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
5366 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005367/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005368{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005369#ifdef MS_WINDOWS
5370 HANDLE hFile;
5371 FILETIME atime, mtime;
5372#else
5373 int result;
5374#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005375
Larry Hastings2f936352014-08-05 14:04:04 +10005376 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005377
Christian Heimesb3c87242013-08-01 00:08:16 +02005378 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07005379
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005380 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005381 PyErr_SetString(PyExc_ValueError,
5382 "utime: you may specify either 'times'"
5383 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005384 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005385 }
5386
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005387 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005388 time_t a_sec, m_sec;
5389 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005390 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005391 PyErr_SetString(PyExc_TypeError,
5392 "utime: 'times' must be either"
5393 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005394 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005395 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005396 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005397 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005398 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005399 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005400 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005401 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005402 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005403 utime.atime_s = a_sec;
5404 utime.atime_ns = a_nsec;
5405 utime.mtime_s = m_sec;
5406 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005407 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005408 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07005409 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005410 PyErr_SetString(PyExc_TypeError,
5411 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005412 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005413 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005414 utime.now = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005415 if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005416 &utime.atime_s, &utime.atime_ns) ||
Victor Stinner1c2fa782020-05-10 11:05:29 +02005417 !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005418 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005419 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005420 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005421 }
5422 else {
5423 /* times and ns are both None/unspecified. use "now". */
5424 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005425 }
5426
Victor Stinner4552ced2015-09-21 22:37:15 +02005427#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005428 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005429 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005430#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005431
Larry Hastings2f936352014-08-05 14:04:04 +10005432 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
5433 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
5434 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005435 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005436
Larry Hastings9cf065c2012-06-22 16:30:09 -07005437#if !defined(HAVE_UTIMENSAT)
5438 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02005439 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005440 "utime: cannot use dir_fd and follow_symlinks "
5441 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005442 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005443 }
5444#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005445
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005446 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
5447 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
5448 return NULL;
5449 }
5450
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005451#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005452 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005453 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5454 NULL, OPEN_EXISTING,
5455 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005456 Py_END_ALLOW_THREADS
5457 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005458 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005459 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005460 }
5461
Larry Hastings9cf065c2012-06-22 16:30:09 -07005462 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005463 GetSystemTimeAsFileTime(&mtime);
5464 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005465 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005466 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005467 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5468 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005469 }
5470 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5471 /* Avoid putting the file name into the error here,
5472 as that may confuse the user into believing that
5473 something is wrong with the file, when it also
5474 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005475 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005476 CloseHandle(hFile);
5477 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005478 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005479 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005480#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005481 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005482
Victor Stinner4552ced2015-09-21 22:37:15 +02005483#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005484 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005485 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005486 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005487#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005488
Victor Stinner528a9ab2015-09-03 21:30:26 +02005489#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Ronald Oussoren41761932020-11-08 10:05:27 +01005490 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
Larry Hastings2f936352014-08-05 14:04:04 +10005491 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Ronald Oussoren41761932020-11-08 10:05:27 +01005492
5493 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07005494#endif
5495
Victor Stinner528a9ab2015-09-03 21:30:26 +02005496#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005497 if (path->fd != -1)
5498 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005499 else
5500#endif
5501
Larry Hastings2f936352014-08-05 14:04:04 +10005502 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005503
5504 Py_END_ALLOW_THREADS
5505
Ronald Oussoren41761932020-11-08 10:05:27 +01005506#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5507 /* See utime_dir_fd implementation */
5508 if (result == -1 && errno == ENOSYS) {
5509 argument_unavailable_error(NULL, "dir_fd");
5510 return NULL;
5511 }
5512#endif
5513
Larry Hastings9cf065c2012-06-22 16:30:09 -07005514 if (result < 0) {
5515 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005516 posix_error();
5517 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005518 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005519
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005520#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005521
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005522 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005523}
5524
Guido van Rossum3b066191991-06-04 19:40:25 +00005525/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005526
Larry Hastings2f936352014-08-05 14:04:04 +10005527
5528/*[clinic input]
5529os._exit
5530
5531 status: int
5532
5533Exit to the system with specified status, without normal exit processing.
5534[clinic start generated code]*/
5535
Larry Hastings2f936352014-08-05 14:04:04 +10005536static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005537os__exit_impl(PyObject *module, int status)
5538/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005539{
5540 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005541 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005542}
5543
Steve Dowercc16be82016-09-08 10:35:16 -07005544#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5545#define EXECV_CHAR wchar_t
5546#else
5547#define EXECV_CHAR char
5548#endif
5549
pxinwrf2d7ac72019-05-21 18:46:37 +08005550#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005551static void
Steve Dowercc16be82016-09-08 10:35:16 -07005552free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005553{
Victor Stinner8c62be82010-05-06 00:08:46 +00005554 Py_ssize_t i;
5555 for (i = 0; i < count; i++)
5556 PyMem_Free(array[i]);
Victor Stinner00d7abd2020-12-01 09:56:42 +01005557 PyMem_Free(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005558}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005559
Berker Peksag81816462016-09-15 20:19:47 +03005560static int
5561fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005562{
Victor Stinner8c62be82010-05-06 00:08:46 +00005563 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005564 PyObject *ub;
5565 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005566#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005567 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005568 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005569 *out = PyUnicode_AsWideCharString(ub, &size);
5570 if (*out)
5571 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005572#else
Berker Peksag81816462016-09-15 20:19:47 +03005573 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005575 size = PyBytes_GET_SIZE(ub);
5576 *out = PyMem_Malloc(size + 1);
5577 if (*out) {
5578 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5579 result = 1;
5580 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005581 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005582#endif
Berker Peksag81816462016-09-15 20:19:47 +03005583 Py_DECREF(ub);
5584 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005585}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005586#endif
5587
pxinwrf2d7ac72019-05-21 18:46:37 +08005588#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005589static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005590parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5591{
Victor Stinner8c62be82010-05-06 00:08:46 +00005592 Py_ssize_t i, pos, envc;
5593 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005594 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005595 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005596
Victor Stinner8c62be82010-05-06 00:08:46 +00005597 i = PyMapping_Size(env);
5598 if (i < 0)
5599 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005600 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005601 if (envlist == NULL) {
5602 PyErr_NoMemory();
5603 return NULL;
5604 }
5605 envc = 0;
5606 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005607 if (!keys)
5608 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005609 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005610 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005611 goto error;
5612 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5613 PyErr_Format(PyExc_TypeError,
5614 "env.keys() or env.values() is not a list");
5615 goto error;
5616 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005617
Victor Stinner8c62be82010-05-06 00:08:46 +00005618 for (pos = 0; pos < i; pos++) {
5619 key = PyList_GetItem(keys, pos);
5620 val = PyList_GetItem(vals, pos);
5621 if (!key || !val)
5622 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005623
Berker Peksag81816462016-09-15 20:19:47 +03005624#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5625 if (!PyUnicode_FSDecoder(key, &key2))
5626 goto error;
5627 if (!PyUnicode_FSDecoder(val, &val2)) {
5628 Py_DECREF(key2);
5629 goto error;
5630 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005631 /* Search from index 1 because on Windows starting '=' is allowed for
5632 defining hidden environment variables. */
5633 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5634 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5635 {
5636 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005637 Py_DECREF(key2);
5638 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005639 goto error;
5640 }
Berker Peksag81816462016-09-15 20:19:47 +03005641 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5642#else
5643 if (!PyUnicode_FSConverter(key, &key2))
5644 goto error;
5645 if (!PyUnicode_FSConverter(val, &val2)) {
5646 Py_DECREF(key2);
5647 goto error;
5648 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005649 if (PyBytes_GET_SIZE(key2) == 0 ||
5650 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5651 {
5652 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005653 Py_DECREF(key2);
5654 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005655 goto error;
5656 }
Berker Peksag81816462016-09-15 20:19:47 +03005657 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5658 PyBytes_AS_STRING(val2));
5659#endif
5660 Py_DECREF(key2);
5661 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005662 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005663 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005664
5665 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5666 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005667 goto error;
5668 }
Berker Peksag81816462016-09-15 20:19:47 +03005669
Steve Dowercc16be82016-09-08 10:35:16 -07005670 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005671 }
5672 Py_DECREF(vals);
5673 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005674
Victor Stinner8c62be82010-05-06 00:08:46 +00005675 envlist[envc] = 0;
5676 *envc_ptr = envc;
5677 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005678
5679error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005680 Py_XDECREF(keys);
5681 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005682 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005683 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005684}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005685
Steve Dowercc16be82016-09-08 10:35:16 -07005686static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005687parse_arglist(PyObject* argv, Py_ssize_t *argc)
5688{
5689 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005690 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005691 if (argvlist == NULL) {
5692 PyErr_NoMemory();
5693 return NULL;
5694 }
5695 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005696 PyObject* item = PySequence_ITEM(argv, i);
5697 if (item == NULL)
5698 goto fail;
5699 if (!fsconvert_strdup(item, &argvlist[i])) {
5700 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005701 goto fail;
5702 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005703 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005704 }
5705 argvlist[*argc] = NULL;
5706 return argvlist;
5707fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005708 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005709 free_string_array(argvlist, *argc);
5710 return NULL;
5711}
Steve Dowercc16be82016-09-08 10:35:16 -07005712
Ross Lagerwall7807c352011-03-17 20:20:30 +02005713#endif
5714
Larry Hastings2f936352014-08-05 14:04:04 +10005715
Ross Lagerwall7807c352011-03-17 20:20:30 +02005716#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005717/*[clinic input]
5718os.execv
5719
Steve Dowercc16be82016-09-08 10:35:16 -07005720 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005721 Path of executable file.
5722 argv: object
5723 Tuple or list of strings.
5724 /
5725
5726Execute an executable path with arguments, replacing current process.
5727[clinic start generated code]*/
5728
Larry Hastings2f936352014-08-05 14:04:04 +10005729static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005730os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5731/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005732{
Steve Dowercc16be82016-09-08 10:35:16 -07005733 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005734 Py_ssize_t argc;
5735
5736 /* execv has two arguments: (path, argv), where
5737 argv is a list or tuple of strings. */
5738
Ross Lagerwall7807c352011-03-17 20:20:30 +02005739 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5740 PyErr_SetString(PyExc_TypeError,
5741 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005742 return NULL;
5743 }
5744 argc = PySequence_Size(argv);
5745 if (argc < 1) {
5746 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005747 return NULL;
5748 }
5749
5750 argvlist = parse_arglist(argv, &argc);
5751 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005752 return NULL;
5753 }
Steve Dowerbce26262016-11-19 19:17:26 -08005754 if (!argvlist[0][0]) {
5755 PyErr_SetString(PyExc_ValueError,
5756 "execv() arg 2 first element cannot be empty");
5757 free_string_array(argvlist, argc);
5758 return NULL;
5759 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005760
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005761 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005762 free_string_array(argvlist, argc);
5763 return NULL;
5764 }
5765
Steve Dowerbce26262016-11-19 19:17:26 -08005766 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005767#ifdef HAVE_WEXECV
5768 _wexecv(path->wide, argvlist);
5769#else
5770 execv(path->narrow, argvlist);
5771#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005772 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005773
5774 /* If we get here it's definitely an error */
5775
5776 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005777 return posix_error();
5778}
5779
Larry Hastings2f936352014-08-05 14:04:04 +10005780
5781/*[clinic input]
5782os.execve
5783
5784 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5785 Path of executable file.
5786 argv: object
5787 Tuple or list of strings.
5788 env: object
5789 Dictionary of strings mapping to strings.
5790
5791Execute an executable path with arguments, replacing current process.
5792[clinic start generated code]*/
5793
Larry Hastings2f936352014-08-05 14:04:04 +10005794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005795os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5796/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005797{
Steve Dowercc16be82016-09-08 10:35:16 -07005798 EXECV_CHAR **argvlist = NULL;
5799 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005800 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005801
Victor Stinner8c62be82010-05-06 00:08:46 +00005802 /* execve has three arguments: (path, argv, env), where
5803 argv is a list or tuple of strings and env is a dictionary
5804 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005805
Ross Lagerwall7807c352011-03-17 20:20:30 +02005806 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005807 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005808 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005809 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005810 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005811 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005812 if (argc < 1) {
5813 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5814 return NULL;
5815 }
5816
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 if (!PyMapping_Check(env)) {
5818 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005819 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005820 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005821 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005822
Ross Lagerwall7807c352011-03-17 20:20:30 +02005823 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005824 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005825 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005826 }
Steve Dowerbce26262016-11-19 19:17:26 -08005827 if (!argvlist[0][0]) {
5828 PyErr_SetString(PyExc_ValueError,
5829 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005830 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005831 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005832
Victor Stinner8c62be82010-05-06 00:08:46 +00005833 envlist = parse_envlist(env, &envc);
5834 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005835 goto fail_0;
5836
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005837 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005838 goto fail_1;
5839 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005840
Steve Dowerbce26262016-11-19 19:17:26 -08005841 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005842#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005843 if (path->fd > -1)
5844 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005845 else
5846#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005847#ifdef HAVE_WEXECV
5848 _wexecve(path->wide, argvlist, envlist);
5849#else
Larry Hastings2f936352014-08-05 14:04:04 +10005850 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005851#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005852 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005853
5854 /* If we get here it's definitely an error */
5855
Alexey Izbyshev83460312018-10-20 03:28:22 +03005856 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005857 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005858 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005859 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005860 if (argvlist)
5861 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005862 return NULL;
5863}
Steve Dowercc16be82016-09-08 10:35:16 -07005864
Larry Hastings9cf065c2012-06-22 16:30:09 -07005865#endif /* HAVE_EXECV */
5866
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005867#ifdef HAVE_POSIX_SPAWN
5868
5869enum posix_spawn_file_actions_identifier {
5870 POSIX_SPAWN_OPEN,
5871 POSIX_SPAWN_CLOSE,
5872 POSIX_SPAWN_DUP2
5873};
5874
William Orr81574b82018-10-01 22:19:56 -07005875#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005876static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005877convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005878#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005879
5880static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005881parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005882 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005883 PyObject *setsigdef, PyObject *scheduler,
5884 posix_spawnattr_t *attrp)
5885{
5886 long all_flags = 0;
5887
5888 errno = posix_spawnattr_init(attrp);
5889 if (errno) {
5890 posix_error();
5891 return -1;
5892 }
5893
5894 if (setpgroup) {
5895 pid_t pgid = PyLong_AsPid(setpgroup);
5896 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5897 goto fail;
5898 }
5899 errno = posix_spawnattr_setpgroup(attrp, pgid);
5900 if (errno) {
5901 posix_error();
5902 goto fail;
5903 }
5904 all_flags |= POSIX_SPAWN_SETPGROUP;
5905 }
5906
5907 if (resetids) {
5908 all_flags |= POSIX_SPAWN_RESETIDS;
5909 }
5910
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005911 if (setsid) {
Ronald Oussoren41761932020-11-08 10:05:27 +01005912#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5913 if (HAVE_POSIX_SPAWN_SETSID_RUNTIME) {
5914#endif
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005915#ifdef POSIX_SPAWN_SETSID
5916 all_flags |= POSIX_SPAWN_SETSID;
5917#elif defined(POSIX_SPAWN_SETSID_NP)
5918 all_flags |= POSIX_SPAWN_SETSID_NP;
5919#else
5920 argument_unavailable_error(func_name, "setsid");
5921 return -1;
5922#endif
Ronald Oussoren41761932020-11-08 10:05:27 +01005923
5924#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5925 } else {
5926 argument_unavailable_error(func_name, "setsid");
5927 return -1;
5928 }
5929#endif /* HAVE_POSIX_SPAWN_SETSID_RUNTIME */
5930
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005931 }
5932
Miss Islington (bot)632d5892021-11-25 03:53:07 -08005933#ifdef HAVE_SIGSET_T
Pablo Galindo254a4662018-09-07 16:44:24 +01005934 if (setsigmask) {
5935 sigset_t set;
5936 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5937 goto fail;
5938 }
5939 errno = posix_spawnattr_setsigmask(attrp, &set);
5940 if (errno) {
5941 posix_error();
5942 goto fail;
5943 }
5944 all_flags |= POSIX_SPAWN_SETSIGMASK;
5945 }
5946
5947 if (setsigdef) {
5948 sigset_t set;
5949 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5950 goto fail;
5951 }
5952 errno = posix_spawnattr_setsigdefault(attrp, &set);
5953 if (errno) {
5954 posix_error();
5955 goto fail;
5956 }
5957 all_flags |= POSIX_SPAWN_SETSIGDEF;
5958 }
Miss Islington (bot)632d5892021-11-25 03:53:07 -08005959#else
5960 if (setsigmask || setsigdef) {
5961 PyErr_SetString(PyExc_NotImplementedError,
5962 "sigset is not supported on this platform");
5963 goto fail;
5964 }
5965#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005966
5967 if (scheduler) {
5968#ifdef POSIX_SPAWN_SETSCHEDULER
5969 PyObject *py_schedpolicy;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005970 PyObject *schedparam_obj;
Pablo Galindo254a4662018-09-07 16:44:24 +01005971 struct sched_param schedparam;
5972
Victor Stinner1c2fa782020-05-10 11:05:29 +02005973 if (!PyArg_ParseTuple(scheduler, "OO"
Pablo Galindo254a4662018-09-07 16:44:24 +01005974 ";A scheduler tuple must have two elements",
Victor Stinner1c2fa782020-05-10 11:05:29 +02005975 &py_schedpolicy, &schedparam_obj)) {
5976 goto fail;
5977 }
5978 if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005979 goto fail;
5980 }
5981 if (py_schedpolicy != Py_None) {
5982 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5983
5984 if (schedpolicy == -1 && PyErr_Occurred()) {
5985 goto fail;
5986 }
5987 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5988 if (errno) {
5989 posix_error();
5990 goto fail;
5991 }
5992 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5993 }
5994 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5995 if (errno) {
5996 posix_error();
5997 goto fail;
5998 }
5999 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
6000#else
6001 PyErr_SetString(PyExc_NotImplementedError,
6002 "The scheduler option is not supported in this system.");
6003 goto fail;
6004#endif
6005 }
6006
6007 errno = posix_spawnattr_setflags(attrp, all_flags);
6008 if (errno) {
6009 posix_error();
6010 goto fail;
6011 }
6012
6013 return 0;
6014
6015fail:
6016 (void)posix_spawnattr_destroy(attrp);
6017 return -1;
6018}
6019
6020static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03006021parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01006022 posix_spawn_file_actions_t *file_actionsp,
6023 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03006024{
6025 PyObject *seq;
6026 PyObject *file_action = NULL;
6027 PyObject *tag_obj;
6028
6029 seq = PySequence_Fast(file_actions,
6030 "file_actions must be a sequence or None");
6031 if (seq == NULL) {
6032 return -1;
6033 }
6034
6035 errno = posix_spawn_file_actions_init(file_actionsp);
6036 if (errno) {
6037 posix_error();
6038 Py_DECREF(seq);
6039 return -1;
6040 }
6041
Zackery Spytzd52a83a2019-06-26 14:54:20 -06006042 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03006043 file_action = PySequence_Fast_GET_ITEM(seq, i);
6044 Py_INCREF(file_action);
6045 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
6046 PyErr_SetString(PyExc_TypeError,
6047 "Each file_actions element must be a non-empty tuple");
6048 goto fail;
6049 }
6050 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
6051 if (tag == -1 && PyErr_Occurred()) {
6052 goto fail;
6053 }
6054
6055 /* Populate the file_actions object */
6056 switch (tag) {
6057 case POSIX_SPAWN_OPEN: {
6058 int fd, oflag;
6059 PyObject *path;
6060 unsigned long mode;
6061 if (!PyArg_ParseTuple(file_action, "OiO&ik"
6062 ";A open file_action tuple must have 5 elements",
6063 &tag_obj, &fd, PyUnicode_FSConverter, &path,
6064 &oflag, &mode))
6065 {
6066 goto fail;
6067 }
Pablo Galindocb970732018-06-19 09:19:50 +01006068 if (PyList_Append(temp_buffer, path)) {
6069 Py_DECREF(path);
6070 goto fail;
6071 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03006072 errno = posix_spawn_file_actions_addopen(file_actionsp,
6073 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01006074 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03006075 if (errno) {
6076 posix_error();
6077 goto fail;
6078 }
6079 break;
6080 }
6081 case POSIX_SPAWN_CLOSE: {
6082 int fd;
6083 if (!PyArg_ParseTuple(file_action, "Oi"
6084 ";A close file_action tuple must have 2 elements",
6085 &tag_obj, &fd))
6086 {
6087 goto fail;
6088 }
6089 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
6090 if (errno) {
6091 posix_error();
6092 goto fail;
6093 }
6094 break;
6095 }
6096 case POSIX_SPAWN_DUP2: {
6097 int fd1, fd2;
6098 if (!PyArg_ParseTuple(file_action, "Oii"
6099 ";A dup2 file_action tuple must have 3 elements",
6100 &tag_obj, &fd1, &fd2))
6101 {
6102 goto fail;
6103 }
6104 errno = posix_spawn_file_actions_adddup2(file_actionsp,
6105 fd1, fd2);
6106 if (errno) {
6107 posix_error();
6108 goto fail;
6109 }
6110 break;
6111 }
6112 default: {
6113 PyErr_SetString(PyExc_TypeError,
6114 "Unknown file_actions identifier");
6115 goto fail;
6116 }
6117 }
6118 Py_DECREF(file_action);
6119 }
Pablo Galindo254a4662018-09-07 16:44:24 +01006120
Serhiy Storchakaef347532018-05-01 16:45:04 +03006121 Py_DECREF(seq);
6122 return 0;
6123
6124fail:
6125 Py_DECREF(seq);
6126 Py_DECREF(file_action);
6127 (void)posix_spawn_file_actions_destroy(file_actionsp);
6128 return -1;
6129}
6130
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006131
6132static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006133py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
6134 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006135 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006136 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006137{
Victor Stinner325e4ba2019-02-01 15:47:24 +01006138 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006139 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006140 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006141 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006142 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01006143 posix_spawnattr_t attr;
6144 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006145 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006146 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01006147 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006148 pid_t pid;
6149 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006150
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006151 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03006152 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006153 like posix.environ. */
6154
Serhiy Storchakaef347532018-05-01 16:45:04 +03006155 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006156 PyErr_Format(PyExc_TypeError,
6157 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006158 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006159 }
6160 argc = PySequence_Size(argv);
6161 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006162 PyErr_Format(PyExc_ValueError,
6163 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006164 return NULL;
6165 }
6166
6167 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006168 PyErr_Format(PyExc_TypeError,
6169 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006170 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006171 }
6172
6173 argvlist = parse_arglist(argv, &argc);
6174 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006175 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006176 }
6177 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006178 PyErr_Format(PyExc_ValueError,
6179 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006180 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006181 }
6182
6183 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006184 if (envlist == NULL) {
6185 goto exit;
6186 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006187
Anthony Shaw948ed8c2019-05-10 12:00:06 +10006188 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01006189 /* There is a bug in old versions of glibc that makes some of the
6190 * helper functions for manipulating file actions not copy the provided
6191 * buffers. The problem is that posix_spawn_file_actions_addopen does not
6192 * copy the value of path for some old versions of glibc (<2.20).
6193 * The use of temp_buffer here is a workaround that keeps the
6194 * python objects that own the buffers alive until posix_spawn gets called.
6195 * Check https://bugs.python.org/issue33630 and
6196 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
6197 temp_buffer = PyList_New(0);
6198 if (!temp_buffer) {
6199 goto exit;
6200 }
6201 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006202 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006203 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03006204 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006205 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006206
Victor Stinner1c2fa782020-05-10 11:05:29 +02006207 if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
Victor Stinner325e4ba2019-02-01 15:47:24 +01006208 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01006209 goto exit;
6210 }
6211 attrp = &attr;
6212
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006213 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006214 goto exit;
6215 }
6216
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006217 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006218#ifdef HAVE_POSIX_SPAWNP
6219 if (use_posix_spawnp) {
6220 err_code = posix_spawnp(&pid, path->narrow,
6221 file_actionsp, attrp, argvlist, envlist);
6222 }
6223 else
6224#endif /* HAVE_POSIX_SPAWNP */
6225 {
6226 err_code = posix_spawn(&pid, path->narrow,
6227 file_actionsp, attrp, argvlist, envlist);
6228 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006229 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006230
Serhiy Storchakaef347532018-05-01 16:45:04 +03006231 if (err_code) {
6232 errno = err_code;
6233 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006234 goto exit;
6235 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006236#ifdef _Py_MEMORY_SANITIZER
6237 __msan_unpoison(&pid, sizeof(pid));
6238#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006239 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006240
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006241exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03006242 if (file_actionsp) {
6243 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006244 }
Pablo Galindo254a4662018-09-07 16:44:24 +01006245 if (attrp) {
6246 (void)posix_spawnattr_destroy(attrp);
6247 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006248 if (envlist) {
6249 free_string_array(envlist, envc);
6250 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006251 if (argvlist) {
6252 free_string_array(argvlist, argc);
6253 }
Pablo Galindocb970732018-06-19 09:19:50 +01006254 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006255 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006256}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006257
6258
6259/*[clinic input]
6260
6261os.posix_spawn
6262 path: path_t
6263 Path of executable file.
6264 argv: object
6265 Tuple or list of strings.
6266 env: object
6267 Dictionary of strings mapping to strings.
6268 /
6269 *
6270 file_actions: object(c_default='NULL') = ()
6271 A sequence of file action tuples.
6272 setpgroup: object = NULL
6273 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6274 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006275 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
6276 setsid: bool(accept={int}) = False
6277 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006278 setsigmask: object(c_default='NULL') = ()
6279 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6280 setsigdef: object(c_default='NULL') = ()
6281 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6282 scheduler: object = NULL
6283 A tuple with the scheduler policy (optional) and parameters.
6284
6285Execute the program specified by path in a new process.
6286[clinic start generated code]*/
6287
6288static PyObject *
6289os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
6290 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006291 PyObject *setpgroup, int resetids, int setsid,
6292 PyObject *setsigmask, PyObject *setsigdef,
6293 PyObject *scheduler)
6294/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006295{
6296 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006297 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006298 scheduler);
6299}
6300 #endif /* HAVE_POSIX_SPAWN */
6301
6302
6303
6304#ifdef HAVE_POSIX_SPAWNP
6305/*[clinic input]
6306
6307os.posix_spawnp
6308 path: path_t
6309 Path of executable file.
6310 argv: object
6311 Tuple or list of strings.
6312 env: object
6313 Dictionary of strings mapping to strings.
6314 /
6315 *
6316 file_actions: object(c_default='NULL') = ()
6317 A sequence of file action tuples.
6318 setpgroup: object = NULL
6319 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6320 resetids: bool(accept={int}) = False
6321 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006322 setsid: bool(accept={int}) = False
6323 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006324 setsigmask: object(c_default='NULL') = ()
6325 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6326 setsigdef: object(c_default='NULL') = ()
6327 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6328 scheduler: object = NULL
6329 A tuple with the scheduler policy (optional) and parameters.
6330
6331Execute the program specified by path in a new process.
6332[clinic start generated code]*/
6333
6334static PyObject *
6335os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
6336 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006337 PyObject *setpgroup, int resetids, int setsid,
6338 PyObject *setsigmask, PyObject *setsigdef,
6339 PyObject *scheduler)
6340/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006341{
6342 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006343 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006344 scheduler);
6345}
6346#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006347
pxinwrf2d7ac72019-05-21 18:46:37 +08006348#ifdef HAVE_RTPSPAWN
6349static intptr_t
6350_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
6351 const char *envp[])
6352{
6353 RTP_ID rtpid;
6354 int status;
6355 pid_t res;
6356 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006357
pxinwrf2d7ac72019-05-21 18:46:37 +08006358 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
6359 uStackSize=0 cannot be used, the default stack size is too small for
6360 Python. */
6361 if (envp) {
6362 rtpid = rtpSpawn(rtpFileName, argv, envp,
6363 100, 0x1000000, 0, VX_FP_TASK);
6364 }
6365 else {
6366 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
6367 100, 0x1000000, 0, VX_FP_TASK);
6368 }
6369 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
6370 do {
6371 res = waitpid((pid_t)rtpid, &status, 0);
6372 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6373
6374 if (res < 0)
6375 return RTP_ID_ERROR;
6376 return ((intptr_t)status);
6377 }
6378 return ((intptr_t)rtpid);
6379}
6380#endif
6381
6382#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10006383/*[clinic input]
6384os.spawnv
6385
6386 mode: int
6387 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006388 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006389 Path of executable file.
6390 argv: object
6391 Tuple or list of strings.
6392 /
6393
6394Execute the program specified by path in a new process.
6395[clinic start generated code]*/
6396
Larry Hastings2f936352014-08-05 14:04:04 +10006397static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006398os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
6399/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006400{
Steve Dowercc16be82016-09-08 10:35:16 -07006401 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10006402 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00006403 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006404 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00006406
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 /* spawnv has three arguments: (mode, path, argv), where
6408 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006409
Victor Stinner8c62be82010-05-06 00:08:46 +00006410 if (PyList_Check(argv)) {
6411 argc = PyList_Size(argv);
6412 getitem = PyList_GetItem;
6413 }
6414 else if (PyTuple_Check(argv)) {
6415 argc = PyTuple_Size(argv);
6416 getitem = PyTuple_GetItem;
6417 }
6418 else {
6419 PyErr_SetString(PyExc_TypeError,
6420 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00006421 return NULL;
6422 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006423 if (argc == 0) {
6424 PyErr_SetString(PyExc_ValueError,
6425 "spawnv() arg 2 cannot be empty");
6426 return NULL;
6427 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006428
Steve Dowercc16be82016-09-08 10:35:16 -07006429 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 return PyErr_NoMemory();
6432 }
6433 for (i = 0; i < argc; i++) {
6434 if (!fsconvert_strdup((*getitem)(argv, i),
6435 &argvlist[i])) {
6436 free_string_array(argvlist, i);
6437 PyErr_SetString(
6438 PyExc_TypeError,
6439 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 return NULL;
6441 }
Steve Dower93ff8722016-11-19 19:03:54 -08006442 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02006443 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08006444 PyErr_SetString(
6445 PyExc_ValueError,
6446 "spawnv() arg 2 first element cannot be empty");
6447 return NULL;
6448 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 }
6450 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006451
pxinwrf2d7ac72019-05-21 18:46:37 +08006452#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 if (mode == _OLD_P_OVERLAY)
6454 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006455#endif
Tim Peters5aa91602002-01-30 05:46:57 +00006456
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006457 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08006458 Py_None) < 0) {
6459 free_string_array(argvlist, argc);
6460 return NULL;
6461 }
6462
Victor Stinner8c62be82010-05-06 00:08:46 +00006463 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006464 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006465#ifdef HAVE_WSPAWNV
6466 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006467#elif defined(HAVE_RTPSPAWN)
6468 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07006469#else
6470 spawnval = _spawnv(mode, path->narrow, argvlist);
6471#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006472 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006473 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00006474
Victor Stinner8c62be82010-05-06 00:08:46 +00006475 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00006476
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 if (spawnval == -1)
6478 return posix_error();
6479 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006480 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006481}
6482
Larry Hastings2f936352014-08-05 14:04:04 +10006483/*[clinic input]
6484os.spawnve
6485
6486 mode: int
6487 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006488 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006489 Path of executable file.
6490 argv: object
6491 Tuple or list of strings.
6492 env: object
6493 Dictionary of strings mapping to strings.
6494 /
6495
6496Execute the program specified by path in a new process.
6497[clinic start generated code]*/
6498
Larry Hastings2f936352014-08-05 14:04:04 +10006499static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006500os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006501 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006502/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006503{
Steve Dowercc16be82016-09-08 10:35:16 -07006504 EXECV_CHAR **argvlist;
6505 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006507 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006508 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006510 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006511
Victor Stinner8c62be82010-05-06 00:08:46 +00006512 /* spawnve has four arguments: (mode, path, argv, env), where
6513 argv is a list or tuple of strings and env is a dictionary
6514 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006515
Victor Stinner8c62be82010-05-06 00:08:46 +00006516 if (PyList_Check(argv)) {
6517 argc = PyList_Size(argv);
6518 getitem = PyList_GetItem;
6519 }
6520 else if (PyTuple_Check(argv)) {
6521 argc = PyTuple_Size(argv);
6522 getitem = PyTuple_GetItem;
6523 }
6524 else {
6525 PyErr_SetString(PyExc_TypeError,
6526 "spawnve() arg 2 must be a tuple or list");
6527 goto fail_0;
6528 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006529 if (argc == 0) {
6530 PyErr_SetString(PyExc_ValueError,
6531 "spawnve() arg 2 cannot be empty");
6532 goto fail_0;
6533 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006534 if (!PyMapping_Check(env)) {
6535 PyErr_SetString(PyExc_TypeError,
6536 "spawnve() arg 3 must be a mapping object");
6537 goto fail_0;
6538 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006539
Steve Dowercc16be82016-09-08 10:35:16 -07006540 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006541 if (argvlist == NULL) {
6542 PyErr_NoMemory();
6543 goto fail_0;
6544 }
6545 for (i = 0; i < argc; i++) {
6546 if (!fsconvert_strdup((*getitem)(argv, i),
6547 &argvlist[i]))
6548 {
6549 lastarg = i;
6550 goto fail_1;
6551 }
Steve Dowerbce26262016-11-19 19:17:26 -08006552 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006553 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006554 PyErr_SetString(
6555 PyExc_ValueError,
6556 "spawnv() arg 2 first element cannot be empty");
6557 goto fail_1;
6558 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 }
6560 lastarg = argc;
6561 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006562
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 envlist = parse_envlist(env, &envc);
6564 if (envlist == NULL)
6565 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006566
pxinwrf2d7ac72019-05-21 18:46:37 +08006567#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006568 if (mode == _OLD_P_OVERLAY)
6569 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006570#endif
Tim Peters25059d32001-12-07 20:35:43 +00006571
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006572 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006573 goto fail_2;
6574 }
6575
Victor Stinner8c62be82010-05-06 00:08:46 +00006576 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006577 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006578#ifdef HAVE_WSPAWNV
6579 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006580#elif defined(HAVE_RTPSPAWN)
6581 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6582 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006583#else
6584 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6585#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006586 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006587 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006588
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 if (spawnval == -1)
6590 (void) posix_error();
6591 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006592 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006593
Saiyang Gou95f60012020-02-04 16:15:00 -08006594 fail_2:
Victor Stinner00d7abd2020-12-01 09:56:42 +01006595 while (--envc >= 0) {
6596 PyMem_Free(envlist[envc]);
6597 }
6598 PyMem_Free(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006599 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006600 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006601 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006603}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006604
Guido van Rossuma1065681999-01-25 23:20:23 +00006605#endif /* HAVE_SPAWNV */
6606
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006607#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006608
6609/* Helper function to validate arguments.
6610 Returns 0 on success. non-zero on failure with a TypeError raised.
6611 If obj is non-NULL it must be callable. */
6612static int
6613check_null_or_callable(PyObject *obj, const char* obj_name)
6614{
6615 if (obj && !PyCallable_Check(obj)) {
6616 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006617 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006618 return -1;
6619 }
6620 return 0;
6621}
6622
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006623/*[clinic input]
6624os.register_at_fork
6625
Gregory P. Smith163468a2017-05-29 10:03:41 -07006626 *
6627 before: object=NULL
6628 A callable to be called in the parent before the fork() syscall.
6629 after_in_child: object=NULL
6630 A callable to be called in the child after fork().
6631 after_in_parent: object=NULL
6632 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006633
Gregory P. Smith163468a2017-05-29 10:03:41 -07006634Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006635
Gregory P. Smith163468a2017-05-29 10:03:41 -07006636'before' callbacks are called in reverse order.
6637'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006638
6639[clinic start generated code]*/
6640
6641static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006642os_register_at_fork_impl(PyObject *module, PyObject *before,
6643 PyObject *after_in_child, PyObject *after_in_parent)
6644/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006645{
6646 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006647
Gregory P. Smith163468a2017-05-29 10:03:41 -07006648 if (!before && !after_in_child && !after_in_parent) {
6649 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6650 return NULL;
6651 }
6652 if (check_null_or_callable(before, "before") ||
6653 check_null_or_callable(after_in_child, "after_in_child") ||
6654 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006655 return NULL;
6656 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006657 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006658
Gregory P. Smith163468a2017-05-29 10:03:41 -07006659 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006660 return NULL;
6661 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006662 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006663 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006664 }
6665 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6666 return NULL;
6667 }
6668 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006669}
6670#endif /* HAVE_FORK */
6671
6672
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006673#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006674/*[clinic input]
6675os.fork1
6676
6677Fork a child process with a single multiplexed (i.e., not bound) thread.
6678
6679Return 0 to child process and PID of child to parent process.
6680[clinic start generated code]*/
6681
Larry Hastings2f936352014-08-05 14:04:04 +10006682static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006683os_fork1_impl(PyObject *module)
6684/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006685{
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006687
Victor Stinner81a7be32020-04-14 15:14:01 +02006688 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006689 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6690 return NULL;
6691 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006692 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006693 pid = fork1();
6694 if (pid == 0) {
6695 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006696 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006697 } else {
6698 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006699 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 }
6701 if (pid == -1)
6702 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006703 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006704}
Larry Hastings2f936352014-08-05 14:04:04 +10006705#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006706
6707
Guido van Rossumad0ee831995-03-01 10:34:45 +00006708#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006709/*[clinic input]
6710os.fork
6711
6712Fork a child process.
6713
6714Return 0 to child process and PID of child to parent process.
6715[clinic start generated code]*/
6716
Larry Hastings2f936352014-08-05 14:04:04 +10006717static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006718os_fork_impl(PyObject *module)
6719/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006720{
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006722 PyInterpreterState *interp = _PyInterpreterState_GET();
6723 if (interp->config._isolated_interpreter) {
6724 PyErr_SetString(PyExc_RuntimeError,
6725 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006726 return NULL;
6727 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006728 if (PySys_Audit("os.fork", NULL) < 0) {
6729 return NULL;
6730 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006731 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 pid = fork();
6733 if (pid == 0) {
6734 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006735 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006736 } else {
6737 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006738 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 }
6740 if (pid == -1)
6741 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006742 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006743}
Larry Hastings2f936352014-08-05 14:04:04 +10006744#endif /* HAVE_FORK */
6745
Guido van Rossum85e3b011991-06-03 12:42:10 +00006746
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006747#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006748#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006749/*[clinic input]
6750os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006751
Larry Hastings2f936352014-08-05 14:04:04 +10006752 policy: int
6753
6754Get the maximum scheduling priority for policy.
6755[clinic start generated code]*/
6756
Larry Hastings2f936352014-08-05 14:04:04 +10006757static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006758os_sched_get_priority_max_impl(PyObject *module, int policy)
6759/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006760{
6761 int max;
6762
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006763 max = sched_get_priority_max(policy);
6764 if (max < 0)
6765 return posix_error();
6766 return PyLong_FromLong(max);
6767}
6768
Larry Hastings2f936352014-08-05 14:04:04 +10006769
6770/*[clinic input]
6771os.sched_get_priority_min
6772
6773 policy: int
6774
6775Get the minimum scheduling priority for policy.
6776[clinic start generated code]*/
6777
Larry Hastings2f936352014-08-05 14:04:04 +10006778static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006779os_sched_get_priority_min_impl(PyObject *module, int policy)
6780/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006781{
6782 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006783 if (min < 0)
6784 return posix_error();
6785 return PyLong_FromLong(min);
6786}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006787#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6788
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006789
Larry Hastings2f936352014-08-05 14:04:04 +10006790#ifdef HAVE_SCHED_SETSCHEDULER
6791/*[clinic input]
6792os.sched_getscheduler
6793 pid: pid_t
6794 /
6795
Min ho Kimc4cacc82019-07-31 08:16:13 +10006796Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006797
6798Passing 0 for pid returns the scheduling policy for the calling process.
6799[clinic start generated code]*/
6800
Larry Hastings2f936352014-08-05 14:04:04 +10006801static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006802os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006803/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006804{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006805 int policy;
6806
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006807 policy = sched_getscheduler(pid);
6808 if (policy < 0)
6809 return posix_error();
6810 return PyLong_FromLong(policy);
6811}
Larry Hastings2f936352014-08-05 14:04:04 +10006812#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006813
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006814
William Orr81574b82018-10-01 22:19:56 -07006815#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006816/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006817class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006818
6819@classmethod
6820os.sched_param.__new__
6821
6822 sched_priority: object
6823 A scheduling parameter.
6824
Eddie Elizondob3966632019-11-05 07:16:14 -08006825Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006826[clinic start generated code]*/
6827
Larry Hastings2f936352014-08-05 14:04:04 +10006828static PyObject *
6829os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006830/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006831{
6832 PyObject *res;
6833
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006834 res = PyStructSequence_New(type);
6835 if (!res)
6836 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006837 Py_INCREF(sched_priority);
6838 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006839 return res;
6840}
6841
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006842PyDoc_VAR(os_sched_param__doc__);
6843
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006844static PyStructSequence_Field sched_param_fields[] = {
6845 {"sched_priority", "the scheduling priority"},
6846 {0}
6847};
6848
6849static PyStructSequence_Desc sched_param_desc = {
6850 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006851 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006852 sched_param_fields,
6853 1
6854};
6855
6856static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006857convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006858{
6859 long priority;
6860
Victor Stinner1c2fa782020-05-10 11:05:29 +02006861 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006862 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6863 return 0;
6864 }
6865 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6866 if (priority == -1 && PyErr_Occurred())
6867 return 0;
6868 if (priority > INT_MAX || priority < INT_MIN) {
6869 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6870 return 0;
6871 }
6872 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6873 return 1;
6874}
William Orr81574b82018-10-01 22:19:56 -07006875#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006876
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006877
6878#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006879/*[clinic input]
6880os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006881
Larry Hastings2f936352014-08-05 14:04:04 +10006882 pid: pid_t
6883 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006884 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006885 /
6886
6887Set the scheduling policy for the process identified by pid.
6888
6889If pid is 0, the calling process is changed.
6890param is an instance of sched_param.
6891[clinic start generated code]*/
6892
Larry Hastings2f936352014-08-05 14:04:04 +10006893static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006894os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006895 PyObject *param_obj)
6896/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006897{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006898 struct sched_param param;
6899 if (!convert_sched_param(module, param_obj, &param)) {
6900 return NULL;
6901 }
6902
Jesus Cea9c822272011-09-10 01:40:52 +02006903 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006904 ** sched_setscheduler() returns 0 in Linux, but the previous
6905 ** scheduling policy under Solaris/Illumos, and others.
6906 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006907 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006908 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006909 return posix_error();
6910 Py_RETURN_NONE;
6911}
Larry Hastings2f936352014-08-05 14:04:04 +10006912#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006913
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006914
6915#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006916/*[clinic input]
6917os.sched_getparam
6918 pid: pid_t
6919 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006920
Larry Hastings2f936352014-08-05 14:04:04 +10006921Returns scheduling parameters for the process identified by pid.
6922
6923If pid is 0, returns parameters for the calling process.
6924Return value is an instance of sched_param.
6925[clinic start generated code]*/
6926
Larry Hastings2f936352014-08-05 14:04:04 +10006927static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006928os_sched_getparam_impl(PyObject *module, pid_t pid)
6929/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006930{
6931 struct sched_param param;
6932 PyObject *result;
6933 PyObject *priority;
6934
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006935 if (sched_getparam(pid, &param))
6936 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006937 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006938 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006939 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006940 return NULL;
6941 priority = PyLong_FromLong(param.sched_priority);
6942 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006943 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006944 return NULL;
6945 }
Larry Hastings2f936352014-08-05 14:04:04 +10006946 PyStructSequence_SET_ITEM(result, 0, priority);
6947 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006948}
6949
Larry Hastings2f936352014-08-05 14:04:04 +10006950
6951/*[clinic input]
6952os.sched_setparam
6953 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006954 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006955 /
6956
6957Set scheduling parameters for the process identified by pid.
6958
6959If pid is 0, sets parameters for the calling process.
6960param should be an instance of sched_param.
6961[clinic start generated code]*/
6962
Larry Hastings2f936352014-08-05 14:04:04 +10006963static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006964os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6965/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006966{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006967 struct sched_param param;
6968 if (!convert_sched_param(module, param_obj, &param)) {
6969 return NULL;
6970 }
6971
6972 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006973 return posix_error();
6974 Py_RETURN_NONE;
6975}
Larry Hastings2f936352014-08-05 14:04:04 +10006976#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006977
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006978
6979#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006980/*[clinic input]
6981os.sched_rr_get_interval -> double
6982 pid: pid_t
6983 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006984
Larry Hastings2f936352014-08-05 14:04:04 +10006985Return the round-robin quantum for the process identified by pid, in seconds.
6986
6987Value returned is a float.
6988[clinic start generated code]*/
6989
Larry Hastings2f936352014-08-05 14:04:04 +10006990static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006991os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6992/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006993{
6994 struct timespec interval;
6995 if (sched_rr_get_interval(pid, &interval)) {
6996 posix_error();
6997 return -1.0;
6998 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006999#ifdef _Py_MEMORY_SANITIZER
7000 __msan_unpoison(&interval, sizeof(interval));
7001#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007002 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
7003}
7004#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05007005
Larry Hastings2f936352014-08-05 14:04:04 +10007006
7007/*[clinic input]
7008os.sched_yield
7009
7010Voluntarily relinquish the CPU.
7011[clinic start generated code]*/
7012
Larry Hastings2f936352014-08-05 14:04:04 +10007013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007014os_sched_yield_impl(PyObject *module)
7015/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007016{
7017 if (sched_yield())
7018 return posix_error();
7019 Py_RETURN_NONE;
7020}
7021
Benjamin Peterson2740af82011-08-02 17:41:34 -05007022#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02007023/* The minimum number of CPUs allocated in a cpu_set_t */
7024static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007025
Larry Hastings2f936352014-08-05 14:04:04 +10007026/*[clinic input]
7027os.sched_setaffinity
7028 pid: pid_t
7029 mask : object
7030 /
7031
7032Set the CPU affinity of the process identified by pid to mask.
7033
7034mask should be an iterable of integers identifying CPUs.
7035[clinic start generated code]*/
7036
Larry Hastings2f936352014-08-05 14:04:04 +10007037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007038os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
7039/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007040{
Antoine Pitrou84869872012-08-04 16:16:35 +02007041 int ncpus;
7042 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007043 cpu_set_t *cpu_set = NULL;
7044 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007045
Larry Hastings2f936352014-08-05 14:04:04 +10007046 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02007047 if (iterator == NULL)
7048 return NULL;
7049
7050 ncpus = NCPUS_START;
7051 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10007052 cpu_set = CPU_ALLOC(ncpus);
7053 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007054 PyErr_NoMemory();
7055 goto error;
7056 }
Larry Hastings2f936352014-08-05 14:04:04 +10007057 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007058
7059 while ((item = PyIter_Next(iterator))) {
7060 long cpu;
7061 if (!PyLong_Check(item)) {
7062 PyErr_Format(PyExc_TypeError,
7063 "expected an iterator of ints, "
7064 "but iterator yielded %R",
7065 Py_TYPE(item));
7066 Py_DECREF(item);
7067 goto error;
7068 }
7069 cpu = PyLong_AsLong(item);
7070 Py_DECREF(item);
7071 if (cpu < 0) {
7072 if (!PyErr_Occurred())
7073 PyErr_SetString(PyExc_ValueError, "negative CPU number");
7074 goto error;
7075 }
7076 if (cpu > INT_MAX - 1) {
7077 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
7078 goto error;
7079 }
7080 if (cpu >= ncpus) {
7081 /* Grow CPU mask to fit the CPU number */
7082 int newncpus = ncpus;
7083 cpu_set_t *newmask;
7084 size_t newsetsize;
7085 while (newncpus <= cpu) {
7086 if (newncpus > INT_MAX / 2)
7087 newncpus = cpu + 1;
7088 else
7089 newncpus = newncpus * 2;
7090 }
7091 newmask = CPU_ALLOC(newncpus);
7092 if (newmask == NULL) {
7093 PyErr_NoMemory();
7094 goto error;
7095 }
7096 newsetsize = CPU_ALLOC_SIZE(newncpus);
7097 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10007098 memcpy(newmask, cpu_set, setsize);
7099 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007100 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007101 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02007102 ncpus = newncpus;
7103 }
Larry Hastings2f936352014-08-05 14:04:04 +10007104 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007105 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07007106 if (PyErr_Occurred()) {
7107 goto error;
7108 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007109 Py_CLEAR(iterator);
7110
Larry Hastings2f936352014-08-05 14:04:04 +10007111 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007112 posix_error();
7113 goto error;
7114 }
Larry Hastings2f936352014-08-05 14:04:04 +10007115 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007116 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02007117
7118error:
Larry Hastings2f936352014-08-05 14:04:04 +10007119 if (cpu_set)
7120 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007121 Py_XDECREF(iterator);
7122 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007123}
7124
Larry Hastings2f936352014-08-05 14:04:04 +10007125
7126/*[clinic input]
7127os.sched_getaffinity
7128 pid: pid_t
7129 /
7130
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01007131Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10007132
7133The affinity is returned as a set of CPU identifiers.
7134[clinic start generated code]*/
7135
Larry Hastings2f936352014-08-05 14:04:04 +10007136static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007137os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03007138/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007139{
Antoine Pitrou84869872012-08-04 16:16:35 +02007140 int cpu, ncpus, count;
7141 size_t setsize;
7142 cpu_set_t *mask = NULL;
7143 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007144
Antoine Pitrou84869872012-08-04 16:16:35 +02007145 ncpus = NCPUS_START;
7146 while (1) {
7147 setsize = CPU_ALLOC_SIZE(ncpus);
7148 mask = CPU_ALLOC(ncpus);
7149 if (mask == NULL)
7150 return PyErr_NoMemory();
7151 if (sched_getaffinity(pid, setsize, mask) == 0)
7152 break;
7153 CPU_FREE(mask);
7154 if (errno != EINVAL)
7155 return posix_error();
7156 if (ncpus > INT_MAX / 2) {
7157 PyErr_SetString(PyExc_OverflowError, "could not allocate "
7158 "a large enough CPU set");
7159 return NULL;
7160 }
7161 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007162 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007163
7164 res = PySet_New(NULL);
7165 if (res == NULL)
7166 goto error;
7167 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
7168 if (CPU_ISSET_S(cpu, setsize, mask)) {
7169 PyObject *cpu_num = PyLong_FromLong(cpu);
7170 --count;
7171 if (cpu_num == NULL)
7172 goto error;
7173 if (PySet_Add(res, cpu_num)) {
7174 Py_DECREF(cpu_num);
7175 goto error;
7176 }
7177 Py_DECREF(cpu_num);
7178 }
7179 }
7180 CPU_FREE(mask);
7181 return res;
7182
7183error:
7184 if (mask)
7185 CPU_FREE(mask);
7186 Py_XDECREF(res);
7187 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007188}
7189
Benjamin Peterson2740af82011-08-02 17:41:34 -05007190#endif /* HAVE_SCHED_SETAFFINITY */
7191
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007192#endif /* HAVE_SCHED_H */
7193
Larry Hastings2f936352014-08-05 14:04:04 +10007194
Neal Norwitzb59798b2003-03-21 01:43:31 +00007195/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00007196#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Victor Stinner57766632020-10-29 15:16:23 +01007197# define DEV_PTY_FILE "/dev/ptc"
7198# define HAVE_DEV_PTMX
Neal Norwitzb59798b2003-03-21 01:43:31 +00007199#else
Victor Stinner57766632020-10-29 15:16:23 +01007200# define DEV_PTY_FILE "/dev/ptmx"
Neal Norwitzb59798b2003-03-21 01:43:31 +00007201#endif
7202
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007203#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00007204#ifdef HAVE_PTY_H
7205#include <pty.h>
7206#else
7207#ifdef HAVE_LIBUTIL_H
7208#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00007209#else
7210#ifdef HAVE_UTIL_H
7211#include <util.h>
7212#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007213#endif /* HAVE_LIBUTIL_H */
7214#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00007215#ifdef HAVE_STROPTS_H
7216#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007217#endif
ngie-eign7745ec42018-02-14 11:54:28 -08007218#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007219
Larry Hastings2f936352014-08-05 14:04:04 +10007220
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007221#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10007222/*[clinic input]
7223os.openpty
7224
7225Open a pseudo-terminal.
7226
7227Return a tuple of (master_fd, slave_fd) containing open file descriptors
7228for both the master and slave ends.
7229[clinic start generated code]*/
7230
Larry Hastings2f936352014-08-05 14:04:04 +10007231static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007232os_openpty_impl(PyObject *module)
7233/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007234{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007235 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007236#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007237 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007238#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007239#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01007241#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00007242 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007243#endif
7244#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00007245
Thomas Wouters70c21a12000-07-14 14:28:33 +00007246#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007247 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007248 goto posix_error;
7249
7250 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7251 goto error;
7252 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
7253 goto error;
7254
Neal Norwitzb59798b2003-03-21 01:43:31 +00007255#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007256 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
7257 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007258 goto posix_error;
7259 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7260 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007261
Victor Stinnerdaf45552013-08-28 00:53:59 +02007262 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00007263 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01007264 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007265
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007266#else
Victor Stinner000de532013-11-25 23:19:58 +01007267 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00007268 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007269 goto posix_error;
7270
Victor Stinner8c62be82010-05-06 00:08:46 +00007271 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007272
Victor Stinner8c62be82010-05-06 00:08:46 +00007273 /* change permission of slave */
7274 if (grantpt(master_fd) < 0) {
7275 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007276 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007277 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007278
Victor Stinner8c62be82010-05-06 00:08:46 +00007279 /* unlock slave */
7280 if (unlockpt(master_fd) < 0) {
7281 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007282 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007283 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007284
Victor Stinner8c62be82010-05-06 00:08:46 +00007285 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007286
Victor Stinner8c62be82010-05-06 00:08:46 +00007287 slave_name = ptsname(master_fd); /* get name of slave */
7288 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007289 goto posix_error;
7290
7291 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01007292 if (slave_fd == -1)
7293 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01007294
7295 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7296 goto posix_error;
7297
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02007298#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00007299 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
7300 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00007301#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00007302 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00007303#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007304#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00007305#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00007306
Victor Stinner8c62be82010-05-06 00:08:46 +00007307 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00007308
Victor Stinnerdaf45552013-08-28 00:53:59 +02007309posix_error:
7310 posix_error();
7311error:
7312 if (master_fd != -1)
7313 close(master_fd);
7314 if (slave_fd != -1)
7315 close(slave_fd);
7316 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00007317}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007318#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007319
Larry Hastings2f936352014-08-05 14:04:04 +10007320
Fred Drake8cef4cf2000-06-28 16:40:38 +00007321#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10007322/*[clinic input]
7323os.forkpty
7324
7325Fork a new process with a new pseudo-terminal as controlling tty.
7326
7327Returns a tuple of (pid, master_fd).
7328Like fork(), return pid of 0 to the child process,
7329and pid of child to the parent process.
7330To both, return fd of newly opened pseudo-terminal.
7331[clinic start generated code]*/
7332
Larry Hastings2f936352014-08-05 14:04:04 +10007333static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007334os_forkpty_impl(PyObject *module)
7335/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007336{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007337 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00007338 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00007339
Victor Stinner81a7be32020-04-14 15:14:01 +02007340 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07007341 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
7342 return NULL;
7343 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007344 if (PySys_Audit("os.forkpty", NULL) < 0) {
7345 return NULL;
7346 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007347 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00007348 pid = forkpty(&master_fd, NULL, NULL, NULL);
7349 if (pid == 0) {
7350 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007351 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00007352 } else {
7353 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007354 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00007355 }
7356 if (pid == -1)
7357 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007358 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00007359}
Larry Hastings2f936352014-08-05 14:04:04 +10007360#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007361
Ross Lagerwall7807c352011-03-17 20:20:30 +02007362
Guido van Rossumad0ee831995-03-01 10:34:45 +00007363#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007364/*[clinic input]
7365os.getegid
7366
7367Return the current process's effective group id.
7368[clinic start generated code]*/
7369
Larry Hastings2f936352014-08-05 14:04:04 +10007370static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007371os_getegid_impl(PyObject *module)
7372/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007373{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007374 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007375}
Larry Hastings2f936352014-08-05 14:04:04 +10007376#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007377
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007378
Guido van Rossumad0ee831995-03-01 10:34:45 +00007379#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007380/*[clinic input]
7381os.geteuid
7382
7383Return the current process's effective user id.
7384[clinic start generated code]*/
7385
Larry Hastings2f936352014-08-05 14:04:04 +10007386static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007387os_geteuid_impl(PyObject *module)
7388/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007389{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007390 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007391}
Larry Hastings2f936352014-08-05 14:04:04 +10007392#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007393
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007394
Guido van Rossumad0ee831995-03-01 10:34:45 +00007395#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007396/*[clinic input]
7397os.getgid
7398
7399Return the current process's group id.
7400[clinic start generated code]*/
7401
Larry Hastings2f936352014-08-05 14:04:04 +10007402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007403os_getgid_impl(PyObject *module)
7404/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007405{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007406 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007407}
Larry Hastings2f936352014-08-05 14:04:04 +10007408#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007410
Berker Peksag39404992016-09-15 20:45:16 +03007411#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10007412/*[clinic input]
7413os.getpid
7414
7415Return the current process id.
7416[clinic start generated code]*/
7417
Larry Hastings2f936352014-08-05 14:04:04 +10007418static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007419os_getpid_impl(PyObject *module)
7420/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007421{
Victor Stinner8c62be82010-05-06 00:08:46 +00007422 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00007423}
Berker Peksag39404992016-09-15 20:45:16 +03007424#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007425
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007426#ifdef NGROUPS_MAX
7427#define MAX_GROUPS NGROUPS_MAX
7428#else
7429 /* defined to be 16 on Solaris7, so this should be a small number */
7430#define MAX_GROUPS 64
7431#endif
7432
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007433#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10007434
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007435#ifdef __APPLE__
7436/*[clinic input]
7437os.getgrouplist
7438
7439 user: str
7440 username to lookup
7441 group as basegid: int
7442 base group id of the user
7443 /
7444
7445Returns a list of groups to which a user belongs.
7446[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007447
7448static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007449os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
7450/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
7451#else
7452/*[clinic input]
7453os.getgrouplist
7454
7455 user: str
7456 username to lookup
7457 group as basegid: gid_t
7458 base group id of the user
7459 /
7460
7461Returns a list of groups to which a user belongs.
7462[clinic start generated code]*/
7463
7464static PyObject *
7465os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
7466/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
7467#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007468{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007469 int i, ngroups;
7470 PyObject *list;
7471#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007472 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007473#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007474 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007475#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007476
7477 /*
7478 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7479 * number of supplimental groups a users can belong to.
7480 * We have to increment it by one because
7481 * getgrouplist() returns both the supplemental groups
7482 * and the primary group, i.e. all of the groups the
7483 * user belongs to.
7484 */
7485 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007486
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007487 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007488#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007489 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007490#else
7491 groups = PyMem_New(gid_t, ngroups);
7492#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007493 if (groups == NULL) {
7494 return PyErr_NoMemory();
7495 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007496
7497 int old_ngroups = ngroups;
7498 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7499 /* Success */
7500 break;
7501 }
7502
7503 /* getgrouplist() fails if the group list is too small */
7504 PyMem_Free(groups);
7505
7506 if (ngroups > old_ngroups) {
7507 /* If the group list is too small, the glibc implementation of
7508 getgrouplist() sets ngroups to the total number of groups and
7509 returns -1. */
7510 }
7511 else {
7512 /* Double the group list size */
7513 if (ngroups > INT_MAX / 2) {
7514 return PyErr_NoMemory();
7515 }
7516 ngroups *= 2;
7517 }
7518
7519 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007520 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007521
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007522#ifdef _Py_MEMORY_SANITIZER
7523 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7524 __msan_unpoison(&ngroups, sizeof(ngroups));
7525 __msan_unpoison(groups, ngroups*sizeof(*groups));
7526#endif
7527
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007528 list = PyList_New(ngroups);
7529 if (list == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01007530 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007531 return NULL;
7532 }
7533
7534 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007535#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007536 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007537#else
7538 PyObject *o = _PyLong_FromGid(groups[i]);
7539#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007540 if (o == NULL) {
7541 Py_DECREF(list);
Victor Stinner00d7abd2020-12-01 09:56:42 +01007542 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007543 return NULL;
7544 }
7545 PyList_SET_ITEM(list, i, o);
7546 }
7547
Victor Stinner00d7abd2020-12-01 09:56:42 +01007548 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007549
7550 return list;
7551}
Larry Hastings2f936352014-08-05 14:04:04 +10007552#endif /* HAVE_GETGROUPLIST */
7553
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007554
Fred Drakec9680921999-12-13 16:37:25 +00007555#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007556/*[clinic input]
7557os.getgroups
7558
7559Return list of supplemental group IDs for the process.
7560[clinic start generated code]*/
7561
Larry Hastings2f936352014-08-05 14:04:04 +10007562static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007563os_getgroups_impl(PyObject *module)
7564/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007565{
7566 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007567 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007568
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007569 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007570 * This is a helper variable to store the intermediate result when
7571 * that happens.
7572 *
7573 * To keep the code readable the OSX behaviour is unconditional,
7574 * according to the POSIX spec this should be safe on all unix-y
7575 * systems.
7576 */
7577 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007578 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007579
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007580#ifdef __APPLE__
7581 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7582 * there are more groups than can fit in grouplist. Therefore, on OS X
7583 * always first call getgroups with length 0 to get the actual number
7584 * of groups.
7585 */
7586 n = getgroups(0, NULL);
7587 if (n < 0) {
7588 return posix_error();
7589 } else if (n <= MAX_GROUPS) {
7590 /* groups will fit in existing array */
7591 alt_grouplist = grouplist;
7592 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007593 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007594 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007595 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007596 }
7597 }
7598
7599 n = getgroups(n, alt_grouplist);
7600 if (n == -1) {
7601 if (alt_grouplist != grouplist) {
7602 PyMem_Free(alt_grouplist);
7603 }
7604 return posix_error();
7605 }
7606#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007607 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007608 if (n < 0) {
7609 if (errno == EINVAL) {
7610 n = getgroups(0, NULL);
7611 if (n == -1) {
7612 return posix_error();
7613 }
7614 if (n == 0) {
7615 /* Avoid malloc(0) */
7616 alt_grouplist = grouplist;
7617 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007618 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007619 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007620 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007621 }
7622 n = getgroups(n, alt_grouplist);
7623 if (n == -1) {
7624 PyMem_Free(alt_grouplist);
7625 return posix_error();
7626 }
7627 }
7628 } else {
7629 return posix_error();
7630 }
7631 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007632#endif
7633
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007634 result = PyList_New(n);
7635 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007636 int i;
7637 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007638 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007640 Py_DECREF(result);
7641 result = NULL;
7642 break;
Fred Drakec9680921999-12-13 16:37:25 +00007643 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007644 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007645 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007646 }
7647
7648 if (alt_grouplist != grouplist) {
7649 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007650 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007651
Fred Drakec9680921999-12-13 16:37:25 +00007652 return result;
7653}
Larry Hastings2f936352014-08-05 14:04:04 +10007654#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007655
Antoine Pitroub7572f02009-12-02 20:46:48 +00007656#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007657#ifdef __APPLE__
7658/*[clinic input]
7659os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007660
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007661 username as oname: FSConverter
7662 gid: int
7663 /
7664
7665Initialize the group access list.
7666
7667Call the system initgroups() to initialize the group access list with all of
7668the groups of which the specified username is a member, plus the specified
7669group id.
7670[clinic start generated code]*/
7671
Antoine Pitroub7572f02009-12-02 20:46:48 +00007672static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007673os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7674/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7675#else
7676/*[clinic input]
7677os.initgroups
7678
7679 username as oname: FSConverter
7680 gid: gid_t
7681 /
7682
7683Initialize the group access list.
7684
7685Call the system initgroups() to initialize the group access list with all of
7686the groups of which the specified username is a member, plus the specified
7687group id.
7688[clinic start generated code]*/
7689
7690static PyObject *
7691os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7692/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7693#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007694{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007695 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007696
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007697 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007699
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007700 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007701}
Larry Hastings2f936352014-08-05 14:04:04 +10007702#endif /* HAVE_INITGROUPS */
7703
Antoine Pitroub7572f02009-12-02 20:46:48 +00007704
Martin v. Löwis606edc12002-06-13 21:09:11 +00007705#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007706/*[clinic input]
7707os.getpgid
7708
7709 pid: pid_t
7710
7711Call the system call getpgid(), and return the result.
7712[clinic start generated code]*/
7713
Larry Hastings2f936352014-08-05 14:04:04 +10007714static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007715os_getpgid_impl(PyObject *module, pid_t pid)
7716/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007717{
7718 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 if (pgid < 0)
7720 return posix_error();
7721 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007722}
7723#endif /* HAVE_GETPGID */
7724
7725
Guido van Rossumb6775db1994-08-01 11:34:53 +00007726#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007727/*[clinic input]
7728os.getpgrp
7729
7730Return the current process group id.
7731[clinic start generated code]*/
7732
Larry Hastings2f936352014-08-05 14:04:04 +10007733static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007734os_getpgrp_impl(PyObject *module)
7735/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007736{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007737#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007738 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007739#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007740 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007741#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007742}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007743#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007744
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007745
Guido van Rossumb6775db1994-08-01 11:34:53 +00007746#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007747/*[clinic input]
7748os.setpgrp
7749
7750Make the current process the leader of its process group.
7751[clinic start generated code]*/
7752
Larry Hastings2f936352014-08-05 14:04:04 +10007753static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007754os_setpgrp_impl(PyObject *module)
7755/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007756{
Guido van Rossum64933891994-10-20 21:56:42 +00007757#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007758 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007759#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007760 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007761#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007762 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007763 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007764}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007765#endif /* HAVE_SETPGRP */
7766
Guido van Rossumad0ee831995-03-01 10:34:45 +00007767#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007768
7769#ifdef MS_WINDOWS
7770#include <tlhelp32.h>
7771
7772static PyObject*
7773win32_getppid()
7774{
7775 HANDLE snapshot;
7776 pid_t mypid;
7777 PyObject* result = NULL;
7778 BOOL have_record;
7779 PROCESSENTRY32 pe;
7780
7781 mypid = getpid(); /* This function never fails */
7782
7783 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7784 if (snapshot == INVALID_HANDLE_VALUE)
7785 return PyErr_SetFromWindowsErr(GetLastError());
7786
7787 pe.dwSize = sizeof(pe);
7788 have_record = Process32First(snapshot, &pe);
7789 while (have_record) {
7790 if (mypid == (pid_t)pe.th32ProcessID) {
7791 /* We could cache the ulong value in a static variable. */
7792 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7793 break;
7794 }
7795
7796 have_record = Process32Next(snapshot, &pe);
7797 }
7798
7799 /* If our loop exits and our pid was not found (result will be NULL)
7800 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7801 * error anyway, so let's raise it. */
7802 if (!result)
7803 result = PyErr_SetFromWindowsErr(GetLastError());
7804
7805 CloseHandle(snapshot);
7806
7807 return result;
7808}
7809#endif /*MS_WINDOWS*/
7810
Larry Hastings2f936352014-08-05 14:04:04 +10007811
7812/*[clinic input]
7813os.getppid
7814
7815Return the parent's process id.
7816
7817If the parent process has already exited, Windows machines will still
7818return its id; others systems will return the id of the 'init' process (1).
7819[clinic start generated code]*/
7820
Larry Hastings2f936352014-08-05 14:04:04 +10007821static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007822os_getppid_impl(PyObject *module)
7823/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007824{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007825#ifdef MS_WINDOWS
7826 return win32_getppid();
7827#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007829#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007830}
7831#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007832
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007833
Fred Drake12c6e2d1999-12-14 21:25:03 +00007834#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007835/*[clinic input]
7836os.getlogin
7837
7838Return the actual login name.
7839[clinic start generated code]*/
7840
Larry Hastings2f936352014-08-05 14:04:04 +10007841static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007842os_getlogin_impl(PyObject *module)
7843/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007844{
Victor Stinner8c62be82010-05-06 00:08:46 +00007845 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007846#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007847 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007848 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007849
7850 if (GetUserNameW(user_name, &num_chars)) {
7851 /* num_chars is the number of unicode chars plus null terminator */
7852 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007853 }
7854 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007855 result = PyErr_SetFromWindowsErr(GetLastError());
7856#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 char *name;
7858 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007859
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 errno = 0;
7861 name = getlogin();
7862 if (name == NULL) {
7863 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007864 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007865 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007866 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 }
7868 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007869 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007871#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007872 return result;
7873}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007874#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007875
Larry Hastings2f936352014-08-05 14:04:04 +10007876
Guido van Rossumad0ee831995-03-01 10:34:45 +00007877#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007878/*[clinic input]
7879os.getuid
7880
7881Return the current process's user id.
7882[clinic start generated code]*/
7883
Larry Hastings2f936352014-08-05 14:04:04 +10007884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007885os_getuid_impl(PyObject *module)
7886/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007887{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007888 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007889}
Larry Hastings2f936352014-08-05 14:04:04 +10007890#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007892
Brian Curtineb24d742010-04-12 17:16:38 +00007893#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007894#define HAVE_KILL
7895#endif /* MS_WINDOWS */
7896
7897#ifdef HAVE_KILL
7898/*[clinic input]
7899os.kill
7900
7901 pid: pid_t
7902 signal: Py_ssize_t
7903 /
7904
7905Kill a process with a signal.
7906[clinic start generated code]*/
7907
Larry Hastings2f936352014-08-05 14:04:04 +10007908static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007909os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7910/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007911{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007912 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7913 return NULL;
7914 }
7915#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007916 if (kill(pid, (int)signal) == -1)
7917 return posix_error();
7918 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007919#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007920 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007921 DWORD sig = (DWORD)signal;
7922 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007924
Victor Stinner8c62be82010-05-06 00:08:46 +00007925 /* Console processes which share a common console can be sent CTRL+C or
7926 CTRL+BREAK events, provided they handle said events. */
7927 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007928 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007929 err = GetLastError();
7930 PyErr_SetFromWindowsErr(err);
7931 }
7932 else
7933 Py_RETURN_NONE;
7934 }
Brian Curtineb24d742010-04-12 17:16:38 +00007935
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7937 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007938 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007939 if (handle == NULL) {
7940 err = GetLastError();
7941 return PyErr_SetFromWindowsErr(err);
7942 }
Brian Curtineb24d742010-04-12 17:16:38 +00007943
Victor Stinner8c62be82010-05-06 00:08:46 +00007944 if (TerminateProcess(handle, sig) == 0) {
7945 err = GetLastError();
7946 result = PyErr_SetFromWindowsErr(err);
7947 } else {
7948 Py_INCREF(Py_None);
7949 result = Py_None;
7950 }
Brian Curtineb24d742010-04-12 17:16:38 +00007951
Victor Stinner8c62be82010-05-06 00:08:46 +00007952 CloseHandle(handle);
7953 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007954#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007955}
Larry Hastings2f936352014-08-05 14:04:04 +10007956#endif /* HAVE_KILL */
7957
7958
7959#ifdef HAVE_KILLPG
7960/*[clinic input]
7961os.killpg
7962
7963 pgid: pid_t
7964 signal: int
7965 /
7966
7967Kill a process group with a signal.
7968[clinic start generated code]*/
7969
Larry Hastings2f936352014-08-05 14:04:04 +10007970static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007971os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7972/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007973{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007974 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7975 return NULL;
7976 }
Larry Hastings2f936352014-08-05 14:04:04 +10007977 /* XXX some man pages make the `pgid` parameter an int, others
7978 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7979 take the same type. Moreover, pid_t is always at least as wide as
7980 int (else compilation of this module fails), which is safe. */
7981 if (killpg(pgid, signal) == -1)
7982 return posix_error();
7983 Py_RETURN_NONE;
7984}
7985#endif /* HAVE_KILLPG */
7986
Brian Curtineb24d742010-04-12 17:16:38 +00007987
Guido van Rossumc0125471996-06-28 18:55:32 +00007988#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007989#ifdef HAVE_SYS_LOCK_H
7990#include <sys/lock.h>
7991#endif
7992
Larry Hastings2f936352014-08-05 14:04:04 +10007993/*[clinic input]
7994os.plock
7995 op: int
7996 /
7997
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007998Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007999[clinic start generated code]*/
8000
Larry Hastings2f936352014-08-05 14:04:04 +10008001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008002os_plock_impl(PyObject *module, int op)
8003/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008004{
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 if (plock(op) == -1)
8006 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008007 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00008008}
Larry Hastings2f936352014-08-05 14:04:04 +10008009#endif /* HAVE_PLOCK */
8010
Guido van Rossumc0125471996-06-28 18:55:32 +00008011
Guido van Rossumb6775db1994-08-01 11:34:53 +00008012#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10008013/*[clinic input]
8014os.setuid
8015
8016 uid: uid_t
8017 /
8018
8019Set the current process's user id.
8020[clinic start generated code]*/
8021
Larry Hastings2f936352014-08-05 14:04:04 +10008022static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008023os_setuid_impl(PyObject *module, uid_t uid)
8024/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008025{
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 if (setuid(uid) < 0)
8027 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008028 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008029}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008030#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008032
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008033#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10008034/*[clinic input]
8035os.seteuid
8036
8037 euid: uid_t
8038 /
8039
8040Set the current process's effective user id.
8041[clinic start generated code]*/
8042
Larry Hastings2f936352014-08-05 14:04:04 +10008043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008044os_seteuid_impl(PyObject *module, uid_t euid)
8045/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008046{
8047 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008048 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008049 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008050}
8051#endif /* HAVE_SETEUID */
8052
Larry Hastings2f936352014-08-05 14:04:04 +10008053
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008054#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10008055/*[clinic input]
8056os.setegid
8057
8058 egid: gid_t
8059 /
8060
8061Set the current process's effective group id.
8062[clinic start generated code]*/
8063
Larry Hastings2f936352014-08-05 14:04:04 +10008064static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008065os_setegid_impl(PyObject *module, gid_t egid)
8066/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008067{
8068 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008069 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008070 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008071}
8072#endif /* HAVE_SETEGID */
8073
Larry Hastings2f936352014-08-05 14:04:04 +10008074
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008075#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10008076/*[clinic input]
8077os.setreuid
8078
8079 ruid: uid_t
8080 euid: uid_t
8081 /
8082
8083Set the current process's real and effective user ids.
8084[clinic start generated code]*/
8085
Larry Hastings2f936352014-08-05 14:04:04 +10008086static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008087os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
8088/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008089{
Victor Stinner8c62be82010-05-06 00:08:46 +00008090 if (setreuid(ruid, euid) < 0) {
8091 return posix_error();
8092 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008093 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00008094 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008095}
8096#endif /* HAVE_SETREUID */
8097
Larry Hastings2f936352014-08-05 14:04:04 +10008098
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008099#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10008100/*[clinic input]
8101os.setregid
8102
8103 rgid: gid_t
8104 egid: gid_t
8105 /
8106
8107Set the current process's real and effective group ids.
8108[clinic start generated code]*/
8109
Larry Hastings2f936352014-08-05 14:04:04 +10008110static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008111os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
8112/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008113{
8114 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008115 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008116 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008117}
8118#endif /* HAVE_SETREGID */
8119
Larry Hastings2f936352014-08-05 14:04:04 +10008120
Guido van Rossumb6775db1994-08-01 11:34:53 +00008121#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10008122/*[clinic input]
8123os.setgid
8124 gid: gid_t
8125 /
8126
8127Set the current process's group id.
8128[clinic start generated code]*/
8129
Larry Hastings2f936352014-08-05 14:04:04 +10008130static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008131os_setgid_impl(PyObject *module, gid_t gid)
8132/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008133{
Victor Stinner8c62be82010-05-06 00:08:46 +00008134 if (setgid(gid) < 0)
8135 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008136 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008137}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008138#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008139
Larry Hastings2f936352014-08-05 14:04:04 +10008140
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008141#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10008142/*[clinic input]
8143os.setgroups
8144
8145 groups: object
8146 /
8147
8148Set the groups of the current process to list.
8149[clinic start generated code]*/
8150
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008152os_setgroups(PyObject *module, PyObject *groups)
8153/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008154{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008155 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00008156 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00008157
Victor Stinner8c62be82010-05-06 00:08:46 +00008158 if (!PySequence_Check(groups)) {
8159 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
8160 return NULL;
8161 }
8162 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008163 if (len < 0) {
8164 return NULL;
8165 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 if (len > MAX_GROUPS) {
8167 PyErr_SetString(PyExc_ValueError, "too many groups");
8168 return NULL;
8169 }
8170 for(i = 0; i < len; i++) {
8171 PyObject *elem;
8172 elem = PySequence_GetItem(groups, i);
8173 if (!elem)
8174 return NULL;
8175 if (!PyLong_Check(elem)) {
8176 PyErr_SetString(PyExc_TypeError,
8177 "groups must be integers");
8178 Py_DECREF(elem);
8179 return NULL;
8180 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008181 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008182 Py_DECREF(elem);
8183 return NULL;
8184 }
8185 }
8186 Py_DECREF(elem);
8187 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008188
Victor Stinner8c62be82010-05-06 00:08:46 +00008189 if (setgroups(len, grouplist) < 0)
8190 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008191 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008192}
8193#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008194
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008195#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
8196static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008197wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008198{
Victor Stinner8c62be82010-05-06 00:08:46 +00008199 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08008200 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008201
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 if (pid == -1)
8203 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008204
Zackery Spytz682107c2019-09-09 09:48:32 -06008205 // If wait succeeded but no child was ready to report status, ru will not
8206 // have been populated.
8207 if (pid == 0) {
8208 memset(ru, 0, sizeof(*ru));
8209 }
8210
Eddie Elizondob3966632019-11-05 07:16:14 -08008211 PyObject *m = PyImport_ImportModuleNoBlock("resource");
8212 if (m == NULL)
8213 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02008214 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08008215 Py_DECREF(m);
8216 if (struct_rusage == NULL)
8217 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008218
Victor Stinner8c62be82010-05-06 00:08:46 +00008219 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
8220 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08008221 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00008222 if (!result)
8223 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008224
8225#ifndef doubletime
8226#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
8227#endif
8228
Victor Stinner8c62be82010-05-06 00:08:46 +00008229 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008230 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00008231 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008232 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008233#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00008234 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
8235 SET_INT(result, 2, ru->ru_maxrss);
8236 SET_INT(result, 3, ru->ru_ixrss);
8237 SET_INT(result, 4, ru->ru_idrss);
8238 SET_INT(result, 5, ru->ru_isrss);
8239 SET_INT(result, 6, ru->ru_minflt);
8240 SET_INT(result, 7, ru->ru_majflt);
8241 SET_INT(result, 8, ru->ru_nswap);
8242 SET_INT(result, 9, ru->ru_inblock);
8243 SET_INT(result, 10, ru->ru_oublock);
8244 SET_INT(result, 11, ru->ru_msgsnd);
8245 SET_INT(result, 12, ru->ru_msgrcv);
8246 SET_INT(result, 13, ru->ru_nsignals);
8247 SET_INT(result, 14, ru->ru_nvcsw);
8248 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008249#undef SET_INT
8250
Victor Stinner8c62be82010-05-06 00:08:46 +00008251 if (PyErr_Occurred()) {
8252 Py_DECREF(result);
8253 return NULL;
8254 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008255
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008257}
8258#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
8259
Larry Hastings2f936352014-08-05 14:04:04 +10008260
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008261#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10008262/*[clinic input]
8263os.wait3
8264
8265 options: int
8266Wait for completion of a child process.
8267
8268Returns a tuple of information about the child process:
8269 (pid, status, rusage)
8270[clinic start generated code]*/
8271
Larry Hastings2f936352014-08-05 14:04:04 +10008272static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008273os_wait3_impl(PyObject *module, int options)
8274/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008275{
Victor Stinner8c62be82010-05-06 00:08:46 +00008276 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008277 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008278 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008279 WAIT_TYPE status;
8280 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008281
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008282 do {
8283 Py_BEGIN_ALLOW_THREADS
8284 pid = wait3(&status, options, &ru);
8285 Py_END_ALLOW_THREADS
8286 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8287 if (pid < 0)
8288 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008289
Victor Stinner1c2fa782020-05-10 11:05:29 +02008290 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008291}
8292#endif /* HAVE_WAIT3 */
8293
Larry Hastings2f936352014-08-05 14:04:04 +10008294
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008295#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10008296/*[clinic input]
8297
8298os.wait4
8299
8300 pid: pid_t
8301 options: int
8302
8303Wait for completion of a specific child process.
8304
8305Returns a tuple of information about the child process:
8306 (pid, status, rusage)
8307[clinic start generated code]*/
8308
Larry Hastings2f936352014-08-05 14:04:04 +10008309static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008310os_wait4_impl(PyObject *module, pid_t pid, int options)
8311/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008312{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008313 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008314 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008315 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008316 WAIT_TYPE status;
8317 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008318
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008319 do {
8320 Py_BEGIN_ALLOW_THREADS
8321 res = wait4(pid, &status, options, &ru);
8322 Py_END_ALLOW_THREADS
8323 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8324 if (res < 0)
8325 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008326
Victor Stinner1c2fa782020-05-10 11:05:29 +02008327 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008328}
8329#endif /* HAVE_WAIT4 */
8330
Larry Hastings2f936352014-08-05 14:04:04 +10008331
Ross Lagerwall7807c352011-03-17 20:20:30 +02008332#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10008333/*[clinic input]
8334os.waitid
8335
8336 idtype: idtype_t
8337 Must be one of be P_PID, P_PGID or P_ALL.
8338 id: id_t
8339 The id to wait on.
8340 options: int
8341 Constructed from the ORing of one or more of WEXITED, WSTOPPED
8342 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
8343 /
8344
8345Returns the result of waiting for a process or processes.
8346
8347Returns either waitid_result or None if WNOHANG is specified and there are
8348no children in a waitable state.
8349[clinic start generated code]*/
8350
Larry Hastings2f936352014-08-05 14:04:04 +10008351static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008352os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
8353/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008354{
8355 PyObject *result;
8356 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008357 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008358 siginfo_t si;
8359 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008360
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008361 do {
8362 Py_BEGIN_ALLOW_THREADS
8363 res = waitid(idtype, id, &si, options);
8364 Py_END_ALLOW_THREADS
8365 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8366 if (res < 0)
8367 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008368
8369 if (si.si_pid == 0)
8370 Py_RETURN_NONE;
8371
Hai Shif707d942020-03-16 21:15:01 +08008372 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008373 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008374 if (!result)
8375 return NULL;
8376
8377 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008378 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008379 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
8380 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
8381 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
8382 if (PyErr_Occurred()) {
8383 Py_DECREF(result);
8384 return NULL;
8385 }
8386
8387 return result;
8388}
Larry Hastings2f936352014-08-05 14:04:04 +10008389#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008390
Larry Hastings2f936352014-08-05 14:04:04 +10008391
8392#if defined(HAVE_WAITPID)
8393/*[clinic input]
8394os.waitpid
8395 pid: pid_t
8396 options: int
8397 /
8398
8399Wait for completion of a given child process.
8400
8401Returns a tuple of information regarding the child process:
8402 (pid, status)
8403
8404The options argument is ignored on Windows.
8405[clinic start generated code]*/
8406
Larry Hastings2f936352014-08-05 14:04:04 +10008407static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008408os_waitpid_impl(PyObject *module, pid_t pid, int options)
8409/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008410{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008411 pid_t res;
8412 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008413 WAIT_TYPE status;
8414 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008415
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008416 do {
8417 Py_BEGIN_ALLOW_THREADS
8418 res = waitpid(pid, &status, options);
8419 Py_END_ALLOW_THREADS
8420 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8421 if (res < 0)
8422 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008423
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008424 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00008425}
Tim Petersab034fa2002-02-01 11:27:43 +00008426#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00008427/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10008428/*[clinic input]
8429os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07008430 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10008431 options: int
8432 /
8433
8434Wait for completion of a given process.
8435
8436Returns a tuple of information regarding the process:
8437 (pid, status << 8)
8438
8439The options argument is ignored on Windows.
8440[clinic start generated code]*/
8441
Larry Hastings2f936352014-08-05 14:04:04 +10008442static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07008443os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07008444/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008445{
8446 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07008447 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008448 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008449
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008450 do {
8451 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08008452 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008453 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08008454 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008455 Py_END_ALLOW_THREADS
8456 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008457 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008458 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008459
Victor Stinner9bee32b2020-04-22 16:30:35 +02008460 unsigned long long ustatus = (unsigned int)status;
8461
Victor Stinner8c62be82010-05-06 00:08:46 +00008462 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02008463 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00008464}
Larry Hastings2f936352014-08-05 14:04:04 +10008465#endif
8466
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008467
Guido van Rossumad0ee831995-03-01 10:34:45 +00008468#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10008469/*[clinic input]
8470os.wait
8471
8472Wait for completion of a child process.
8473
8474Returns a tuple of information about the child process:
8475 (pid, status)
8476[clinic start generated code]*/
8477
Larry Hastings2f936352014-08-05 14:04:04 +10008478static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008479os_wait_impl(PyObject *module)
8480/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008481{
Victor Stinner8c62be82010-05-06 00:08:46 +00008482 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008483 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008484 WAIT_TYPE status;
8485 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008486
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008487 do {
8488 Py_BEGIN_ALLOW_THREADS
8489 pid = wait(&status);
8490 Py_END_ALLOW_THREADS
8491 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8492 if (pid < 0)
8493 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008494
Victor Stinner8c62be82010-05-06 00:08:46 +00008495 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008496}
Larry Hastings2f936352014-08-05 14:04:04 +10008497#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008498
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008499#if defined(__linux__) && defined(__NR_pidfd_open)
8500/*[clinic input]
8501os.pidfd_open
8502 pid: pid_t
8503 flags: unsigned_int = 0
8504
8505Return a file descriptor referring to the process *pid*.
8506
8507The descriptor can be used to perform process management without races and
8508signals.
8509[clinic start generated code]*/
8510
8511static PyObject *
8512os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8513/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8514{
8515 int fd = syscall(__NR_pidfd_open, pid, flags);
8516 if (fd < 0) {
8517 return posix_error();
8518 }
8519 return PyLong_FromLong(fd);
8520}
8521#endif
8522
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008523
Larry Hastings9cf065c2012-06-22 16:30:09 -07008524#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008525/*[clinic input]
8526os.readlink
8527
8528 path: path_t
8529 *
8530 dir_fd: dir_fd(requires='readlinkat') = None
8531
8532Return a string representing the path to which the symbolic link points.
8533
8534If dir_fd is not None, it should be a file descriptor open to a directory,
8535and path should be relative; path will then be relative to that directory.
8536
8537dir_fd may not be implemented on your platform. If it is unavailable,
8538using it will raise a NotImplementedError.
8539[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008540
Barry Warsaw53699e91996-12-10 23:23:01 +00008541static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008542os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8543/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008544{
Berker Peksage0b5b202018-08-15 13:03:41 +03008545#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008546 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008547 ssize_t length;
Ronald Oussoren41761932020-11-08 10:05:27 +01008548#ifdef HAVE_READLINKAT
8549 int readlinkat_unavailable = 0;
8550#endif
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008551
8552 Py_BEGIN_ALLOW_THREADS
8553#ifdef HAVE_READLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01008554 if (dir_fd != DEFAULT_DIR_FD) {
8555 if (HAVE_READLINKAT_RUNTIME) {
8556 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8557 } else {
8558 readlinkat_unavailable = 1;
8559 }
8560 } else
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008561#endif
8562 length = readlink(path->narrow, buffer, MAXPATHLEN);
8563 Py_END_ALLOW_THREADS
8564
Ronald Oussoren41761932020-11-08 10:05:27 +01008565#ifdef HAVE_READLINKAT
8566 if (readlinkat_unavailable) {
8567 argument_unavailable_error(NULL, "dir_fd");
8568 return NULL;
8569 }
8570#endif
8571
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008572 if (length < 0) {
8573 return path_error(path);
8574 }
8575 buffer[length] = '\0';
8576
8577 if (PyUnicode_Check(path->object))
8578 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8579 else
8580 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008581#elif defined(MS_WINDOWS)
8582 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008583 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008584 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008585 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8586 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008587 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008588
Larry Hastings2f936352014-08-05 14:04:04 +10008589 /* First get a handle to the reparse point */
8590 Py_BEGIN_ALLOW_THREADS
8591 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008592 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008593 0,
8594 0,
8595 0,
8596 OPEN_EXISTING,
8597 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8598 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008599 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8600 /* New call DeviceIoControl to read the reparse point */
8601 io_result = DeviceIoControl(
8602 reparse_point_handle,
8603 FSCTL_GET_REPARSE_POINT,
8604 0, 0, /* in buffer */
8605 target_buffer, sizeof(target_buffer),
8606 &n_bytes_returned,
8607 0 /* we're not using OVERLAPPED_IO */
8608 );
8609 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008610 }
Larry Hastings2f936352014-08-05 14:04:04 +10008611 Py_END_ALLOW_THREADS
8612
Berker Peksage0b5b202018-08-15 13:03:41 +03008613 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008614 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008615 }
Larry Hastings2f936352014-08-05 14:04:04 +10008616
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008617 wchar_t *name = NULL;
8618 Py_ssize_t nameLen = 0;
8619 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008620 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008621 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8622 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8623 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008624 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008625 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8626 {
8627 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8628 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8629 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8630 }
8631 else
8632 {
8633 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8634 }
8635 if (name) {
8636 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8637 /* Our buffer is mutable, so this is okay */
8638 name[1] = L'\\';
8639 }
8640 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008641 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008642 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8643 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008644 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008645 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008646#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008647}
Berker Peksage0b5b202018-08-15 13:03:41 +03008648#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008649
Larry Hastings9cf065c2012-06-22 16:30:09 -07008650#if defined(MS_WINDOWS)
8651
Steve Dower6921e732018-03-05 14:26:08 -08008652/* Remove the last portion of the path - return 0 on success */
8653static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008654_dirnameW(WCHAR *path)
8655{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008656 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008657 size_t length = wcsnlen_s(path, MAX_PATH);
8658 if (length == MAX_PATH) {
8659 return -1;
8660 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008661
8662 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008663 for(ptr = path + length; ptr != path; ptr--) {
8664 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008665 break;
Steve Dower6921e732018-03-05 14:26:08 -08008666 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008667 }
8668 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008669 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008670}
8671
Minmin Gong7f21c9a2020-05-18 09:17:19 -07008672#endif
8673
8674#ifdef HAVE_SYMLINK
8675
8676#if defined(MS_WINDOWS)
8677
Victor Stinner31b3b922013-06-05 01:49:17 +02008678/* Is this path absolute? */
8679static int
8680_is_absW(const WCHAR *path)
8681{
Steve Dower6921e732018-03-05 14:26:08 -08008682 return path[0] == L'\\' || path[0] == L'/' ||
8683 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008684}
8685
Steve Dower6921e732018-03-05 14:26:08 -08008686/* join root and rest with a backslash - return 0 on success */
8687static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008688_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8689{
Victor Stinner31b3b922013-06-05 01:49:17 +02008690 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008691 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008692 }
8693
Steve Dower6921e732018-03-05 14:26:08 -08008694 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8695 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008696 }
Steve Dower6921e732018-03-05 14:26:08 -08008697
8698 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8699 return -1;
8700 }
8701
8702 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008703}
8704
Victor Stinner31b3b922013-06-05 01:49:17 +02008705/* Return True if the path at src relative to dest is a directory */
8706static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008707_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008708{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008709 WIN32_FILE_ATTRIBUTE_DATA src_info;
8710 WCHAR dest_parent[MAX_PATH];
8711 WCHAR src_resolved[MAX_PATH] = L"";
8712
8713 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008714 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8715 _dirnameW(dest_parent)) {
8716 return 0;
8717 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008718 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008719 if (_joinW(src_resolved, dest_parent, src)) {
8720 return 0;
8721 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008722 return (
8723 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8724 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8725 );
8726}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008727#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008728
Larry Hastings2f936352014-08-05 14:04:04 +10008729
8730/*[clinic input]
8731os.symlink
8732 src: path_t
8733 dst: path_t
8734 target_is_directory: bool = False
8735 *
8736 dir_fd: dir_fd(requires='symlinkat')=None
8737
8738# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8739
8740Create a symbolic link pointing to src named dst.
8741
8742target_is_directory is required on Windows if the target is to be
8743 interpreted as a directory. (On Windows, symlink requires
8744 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8745 target_is_directory is ignored on non-Windows platforms.
8746
8747If dir_fd is not None, it should be a file descriptor open to a directory,
8748 and path should be relative; path will then be relative to that directory.
8749dir_fd may not be implemented on your platform.
8750 If it is unavailable, using it will raise a NotImplementedError.
8751
8752[clinic start generated code]*/
8753
Larry Hastings2f936352014-08-05 14:04:04 +10008754static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008755os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008756 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008757/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008758{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008759#ifdef MS_WINDOWS
8760 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008761 DWORD flags = 0;
8762
8763 /* Assumed true, set to false if detected to not be available. */
8764 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008765#else
8766 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01008767#ifdef HAVE_SYMLINKAT
8768 int symlinkat_unavailable = 0;
8769#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07008770#endif
8771
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008772 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8773 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8774 return NULL;
8775 }
8776
Larry Hastings9cf065c2012-06-22 16:30:09 -07008777#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008778
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008779 if (windows_has_symlink_unprivileged_flag) {
8780 /* Allow non-admin symlinks if system allows it. */
8781 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8782 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008783
Larry Hastings9cf065c2012-06-22 16:30:09 -07008784 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008785 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008786 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8787 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8788 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8789 }
8790
8791 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008792 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008793 Py_END_ALLOW_THREADS
8794
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008795 if (windows_has_symlink_unprivileged_flag && !result &&
8796 ERROR_INVALID_PARAMETER == GetLastError()) {
8797
8798 Py_BEGIN_ALLOW_THREADS
8799 _Py_BEGIN_SUPPRESS_IPH
8800 /* This error might be caused by
8801 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8802 Try again, and update windows_has_symlink_unprivileged_flag if we
8803 are successful this time.
8804
8805 NOTE: There is a risk of a race condition here if there are other
8806 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8807 another process (or thread) changes that condition in between our
8808 calls to CreateSymbolicLink.
8809 */
8810 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8811 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8812 _Py_END_SUPPRESS_IPH
8813 Py_END_ALLOW_THREADS
8814
8815 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8816 windows_has_symlink_unprivileged_flag = FALSE;
8817 }
8818 }
8819
Larry Hastings2f936352014-08-05 14:04:04 +10008820 if (!result)
8821 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008822
8823#else
8824
Steve Dower6921e732018-03-05 14:26:08 -08008825 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8826 PyErr_SetString(PyExc_ValueError,
8827 "symlink: src and dst must be the same type");
8828 return NULL;
8829 }
8830
Larry Hastings9cf065c2012-06-22 16:30:09 -07008831 Py_BEGIN_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01008832#ifdef HAVE_SYMLINKAT
8833 if (dir_fd != DEFAULT_DIR_FD) {
8834 if (HAVE_SYMLINKAT_RUNTIME) {
8835 result = symlinkat(src->narrow, dir_fd, dst->narrow);
8836 } else {
8837 symlinkat_unavailable = 1;
8838 }
8839 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008840#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008841 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008842 Py_END_ALLOW_THREADS
8843
Ronald Oussoren41761932020-11-08 10:05:27 +01008844#ifdef HAVE_SYMLINKAT
8845 if (symlinkat_unavailable) {
8846 argument_unavailable_error(NULL, "dir_fd");
8847 return NULL;
8848 }
8849#endif
8850
Larry Hastings2f936352014-08-05 14:04:04 +10008851 if (result)
8852 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008853#endif
8854
Larry Hastings2f936352014-08-05 14:04:04 +10008855 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008856}
8857#endif /* HAVE_SYMLINK */
8858
Larry Hastings9cf065c2012-06-22 16:30:09 -07008859
Brian Curtind40e6f72010-07-08 21:39:08 +00008860
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008861
Larry Hastings605a62d2012-06-24 04:33:36 -07008862static PyStructSequence_Field times_result_fields[] = {
8863 {"user", "user time"},
8864 {"system", "system time"},
8865 {"children_user", "user time of children"},
8866 {"children_system", "system time of children"},
8867 {"elapsed", "elapsed time since an arbitrary point in the past"},
8868 {NULL}
8869};
8870
8871PyDoc_STRVAR(times_result__doc__,
8872"times_result: Result from os.times().\n\n\
8873This object may be accessed either as a tuple of\n\
8874 (user, system, children_user, children_system, elapsed),\n\
8875or via the attributes user, system, children_user, children_system,\n\
8876and elapsed.\n\
8877\n\
8878See os.times for more information.");
8879
8880static PyStructSequence_Desc times_result_desc = {
8881 "times_result", /* name */
8882 times_result__doc__, /* doc */
8883 times_result_fields,
8884 5
8885};
8886
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008887#ifdef MS_WINDOWS
8888#define HAVE_TIMES /* mandatory, for the method table */
8889#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008890
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008891#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008892
8893static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008894build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008895 double children_user, double children_system,
8896 double elapsed)
8897{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008898 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008899 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008900 if (value == NULL)
8901 return NULL;
8902
8903#define SET(i, field) \
8904 { \
8905 PyObject *o = PyFloat_FromDouble(field); \
8906 if (!o) { \
8907 Py_DECREF(value); \
8908 return NULL; \
8909 } \
8910 PyStructSequence_SET_ITEM(value, i, o); \
8911 } \
8912
8913 SET(0, user);
8914 SET(1, system);
8915 SET(2, children_user);
8916 SET(3, children_system);
8917 SET(4, elapsed);
8918
8919#undef SET
8920
8921 return value;
8922}
8923
Larry Hastings605a62d2012-06-24 04:33:36 -07008924
Larry Hastings2f936352014-08-05 14:04:04 +10008925#ifndef MS_WINDOWS
8926#define NEED_TICKS_PER_SECOND
8927static long ticks_per_second = -1;
8928#endif /* MS_WINDOWS */
8929
8930/*[clinic input]
8931os.times
8932
8933Return a collection containing process timing information.
8934
8935The object returned behaves like a named tuple with these fields:
8936 (utime, stime, cutime, cstime, elapsed_time)
8937All fields are floating point numbers.
8938[clinic start generated code]*/
8939
Larry Hastings2f936352014-08-05 14:04:04 +10008940static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008941os_times_impl(PyObject *module)
8942/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008943#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008944{
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 FILETIME create, exit, kernel, user;
8946 HANDLE hProc;
8947 hProc = GetCurrentProcess();
8948 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8949 /* The fields of a FILETIME structure are the hi and lo part
8950 of a 64-bit value expressed in 100 nanosecond units.
8951 1e7 is one second in such units; 1e-7 the inverse.
8952 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8953 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008954 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008955 (double)(user.dwHighDateTime*429.4967296 +
8956 user.dwLowDateTime*1e-7),
8957 (double)(kernel.dwHighDateTime*429.4967296 +
8958 kernel.dwLowDateTime*1e-7),
8959 (double)0,
8960 (double)0,
8961 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008962}
Larry Hastings2f936352014-08-05 14:04:04 +10008963#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008964{
Larry Hastings2f936352014-08-05 14:04:04 +10008965
8966
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008967 struct tms t;
8968 clock_t c;
8969 errno = 0;
8970 c = times(&t);
8971 if (c == (clock_t) -1)
8972 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008973 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008974 (double)t.tms_utime / ticks_per_second,
8975 (double)t.tms_stime / ticks_per_second,
8976 (double)t.tms_cutime / ticks_per_second,
8977 (double)t.tms_cstime / ticks_per_second,
8978 (double)c / ticks_per_second);
8979}
Larry Hastings2f936352014-08-05 14:04:04 +10008980#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008981#endif /* HAVE_TIMES */
8982
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008983
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008984#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008985/*[clinic input]
8986os.getsid
8987
8988 pid: pid_t
8989 /
8990
8991Call the system call getsid(pid) and return the result.
8992[clinic start generated code]*/
8993
Larry Hastings2f936352014-08-05 14:04:04 +10008994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008995os_getsid_impl(PyObject *module, pid_t pid)
8996/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008997{
Victor Stinner8c62be82010-05-06 00:08:46 +00008998 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008999 sid = getsid(pid);
9000 if (sid < 0)
9001 return posix_error();
9002 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009003}
9004#endif /* HAVE_GETSID */
9005
9006
Guido van Rossumb6775db1994-08-01 11:34:53 +00009007#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10009008/*[clinic input]
9009os.setsid
9010
9011Call the system call setsid().
9012[clinic start generated code]*/
9013
Larry Hastings2f936352014-08-05 14:04:04 +10009014static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009015os_setsid_impl(PyObject *module)
9016/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00009017{
Victor Stinner8c62be82010-05-06 00:08:46 +00009018 if (setsid() < 0)
9019 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009020 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00009021}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009022#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00009023
Larry Hastings2f936352014-08-05 14:04:04 +10009024
Guido van Rossumb6775db1994-08-01 11:34:53 +00009025#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10009026/*[clinic input]
9027os.setpgid
9028
9029 pid: pid_t
9030 pgrp: pid_t
9031 /
9032
9033Call the system call setpgid(pid, pgrp).
9034[clinic start generated code]*/
9035
Larry Hastings2f936352014-08-05 14:04:04 +10009036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009037os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
9038/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009039{
Victor Stinner8c62be82010-05-06 00:08:46 +00009040 if (setpgid(pid, pgrp) < 0)
9041 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009042 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00009043}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009044#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00009045
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009046
Guido van Rossumb6775db1994-08-01 11:34:53 +00009047#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10009048/*[clinic input]
9049os.tcgetpgrp
9050
9051 fd: int
9052 /
9053
9054Return the process group associated with the terminal specified by fd.
9055[clinic start generated code]*/
9056
Larry Hastings2f936352014-08-05 14:04:04 +10009057static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009058os_tcgetpgrp_impl(PyObject *module, int fd)
9059/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009060{
9061 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00009062 if (pgid < 0)
9063 return posix_error();
9064 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00009065}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009066#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00009067
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009068
Guido van Rossumb6775db1994-08-01 11:34:53 +00009069#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10009070/*[clinic input]
9071os.tcsetpgrp
9072
9073 fd: int
9074 pgid: pid_t
9075 /
9076
9077Set the process group associated with the terminal specified by fd.
9078[clinic start generated code]*/
9079
Larry Hastings2f936352014-08-05 14:04:04 +10009080static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009081os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
9082/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009083{
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 if (tcsetpgrp(fd, pgid) < 0)
9085 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009086 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00009087}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009088#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00009089
Guido van Rossum687dd131993-05-17 08:34:16 +00009090/* Functions acting on file descriptors */
9091
Victor Stinnerdaf45552013-08-28 00:53:59 +02009092#ifdef O_CLOEXEC
9093extern int _Py_open_cloexec_works;
9094#endif
9095
Larry Hastings2f936352014-08-05 14:04:04 +10009096
9097/*[clinic input]
9098os.open -> int
9099 path: path_t
9100 flags: int
9101 mode: int = 0o777
9102 *
9103 dir_fd: dir_fd(requires='openat') = None
9104
9105# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
9106
9107Open a file for low level IO. Returns a file descriptor (integer).
9108
9109If dir_fd is not None, it should be a file descriptor open to a directory,
9110 and path should be relative; path will then be relative to that directory.
9111dir_fd may not be implemented on your platform.
9112 If it is unavailable, using it will raise a NotImplementedError.
9113[clinic start generated code]*/
9114
Larry Hastings2f936352014-08-05 14:04:04 +10009115static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009116os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
9117/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009118{
9119 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009120 int async_err = 0;
Ronald Oussoren41761932020-11-08 10:05:27 +01009121#ifdef HAVE_OPENAT
9122 int openat_unavailable = 0;
9123#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009124
Victor Stinnerdaf45552013-08-28 00:53:59 +02009125#ifdef O_CLOEXEC
9126 int *atomic_flag_works = &_Py_open_cloexec_works;
9127#elif !defined(MS_WINDOWS)
9128 int *atomic_flag_works = NULL;
9129#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00009130
Victor Stinnerdaf45552013-08-28 00:53:59 +02009131#ifdef MS_WINDOWS
9132 flags |= O_NOINHERIT;
9133#elif defined(O_CLOEXEC)
9134 flags |= O_CLOEXEC;
9135#endif
9136
Steve Dowerb82e17e2019-05-23 08:45:22 -07009137 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
9138 return -1;
9139 }
9140
Steve Dower8fc89802015-04-12 00:26:27 -04009141 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009142 do {
9143 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07009144#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009145 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009146#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07009147#ifdef HAVE_OPENAT
Ronald Oussoren41761932020-11-08 10:05:27 +01009148 if (dir_fd != DEFAULT_DIR_FD) {
9149 if (HAVE_OPENAT_RUNTIME) {
9150 fd = openat(dir_fd, path->narrow, flags, mode);
9151
9152 } else {
9153 openat_unavailable = 1;
9154 fd = -1;
9155 }
9156 } else
Steve Dower6230aaf2016-09-09 09:03:15 -07009157#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009158 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009159#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009160 Py_END_ALLOW_THREADS
9161 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009162 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00009163
Ronald Oussoren41761932020-11-08 10:05:27 +01009164#ifdef HAVE_OPENAT
9165 if (openat_unavailable) {
9166 argument_unavailable_error(NULL, "dir_fd");
9167 return -1;
9168 }
9169#endif
9170
Victor Stinnerd3ffd322015-09-15 10:11:03 +02009171 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009172 if (!async_err)
9173 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10009174 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009175 }
9176
Victor Stinnerdaf45552013-08-28 00:53:59 +02009177#ifndef MS_WINDOWS
9178 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
9179 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10009180 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009181 }
9182#endif
9183
Larry Hastings2f936352014-08-05 14:04:04 +10009184 return fd;
9185}
9186
9187
9188/*[clinic input]
9189os.close
9190
9191 fd: int
9192
9193Close a file descriptor.
9194[clinic start generated code]*/
9195
Barry Warsaw53699e91996-12-10 23:23:01 +00009196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009197os_close_impl(PyObject *module, int fd)
9198/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009199{
Larry Hastings2f936352014-08-05 14:04:04 +10009200 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009201 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
9202 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
9203 * for more details.
9204 */
Victor Stinner8c62be82010-05-06 00:08:46 +00009205 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009206 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009207 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04009208 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009209 Py_END_ALLOW_THREADS
9210 if (res < 0)
9211 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009212 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00009213}
9214
Larry Hastings2f936352014-08-05 14:04:04 +10009215/*[clinic input]
9216os.closerange
9217
9218 fd_low: int
9219 fd_high: int
9220 /
9221
9222Closes all file descriptors in [fd_low, fd_high), ignoring errors.
9223[clinic start generated code]*/
9224
Larry Hastings2f936352014-08-05 14:04:04 +10009225static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009226os_closerange_impl(PyObject *module, int fd_low, int fd_high)
9227/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009228{
Victor Stinner8c62be82010-05-06 00:08:46 +00009229 Py_BEGIN_ALLOW_THREADS
Kyle Evansc230fde2020-10-11 13:54:11 -05009230 _Py_closerange(fd_low, fd_high - 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00009231 Py_END_ALLOW_THREADS
9232 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00009233}
9234
9235
Larry Hastings2f936352014-08-05 14:04:04 +10009236/*[clinic input]
9237os.dup -> int
9238
9239 fd: int
9240 /
9241
9242Return a duplicate of a file descriptor.
9243[clinic start generated code]*/
9244
Larry Hastings2f936352014-08-05 14:04:04 +10009245static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009246os_dup_impl(PyObject *module, int fd)
9247/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009248{
9249 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00009250}
9251
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009252
Larry Hastings2f936352014-08-05 14:04:04 +10009253/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009254os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10009255 fd: int
9256 fd2: int
9257 inheritable: bool=True
9258
9259Duplicate file descriptor.
9260[clinic start generated code]*/
9261
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009262static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009263os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009264/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009265{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01009266 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009267#if defined(HAVE_DUP3) && \
9268 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
9269 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03009270 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009271#endif
9272
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009273 if (fd < 0 || fd2 < 0) {
9274 posix_error();
9275 return -1;
9276 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009277
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009278 /* dup2() can fail with EINTR if the target FD is already open, because it
9279 * then has to be closed. See os_close_impl() for why we don't handle EINTR
9280 * upon close(), and therefore below.
9281 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02009282#ifdef MS_WINDOWS
9283 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009284 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04009286 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009287 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009288 if (res < 0) {
9289 posix_error();
9290 return -1;
9291 }
9292 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02009293
9294 /* Character files like console cannot be make non-inheritable */
9295 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9296 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009297 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009298 }
9299
9300#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
9301 Py_BEGIN_ALLOW_THREADS
9302 if (!inheritable)
9303 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
9304 else
9305 res = dup2(fd, fd2);
9306 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009307 if (res < 0) {
9308 posix_error();
9309 return -1;
9310 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009311
9312#else
9313
9314#ifdef HAVE_DUP3
9315 if (!inheritable && dup3_works != 0) {
9316 Py_BEGIN_ALLOW_THREADS
9317 res = dup3(fd, fd2, O_CLOEXEC);
9318 Py_END_ALLOW_THREADS
9319 if (res < 0) {
9320 if (dup3_works == -1)
9321 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009322 if (dup3_works) {
9323 posix_error();
9324 return -1;
9325 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009326 }
9327 }
9328
9329 if (inheritable || dup3_works == 0)
9330 {
9331#endif
9332 Py_BEGIN_ALLOW_THREADS
9333 res = dup2(fd, fd2);
9334 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009335 if (res < 0) {
9336 posix_error();
9337 return -1;
9338 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009339
9340 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9341 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009342 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009343 }
9344#ifdef HAVE_DUP3
9345 }
9346#endif
9347
9348#endif
9349
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009350 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00009351}
9352
Larry Hastings2f936352014-08-05 14:04:04 +10009353
Ross Lagerwall7807c352011-03-17 20:20:30 +02009354#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10009355/*[clinic input]
9356os.lockf
9357
9358 fd: int
9359 An open file descriptor.
9360 command: int
9361 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
9362 length: Py_off_t
9363 The number of bytes to lock, starting at the current position.
9364 /
9365
9366Apply, test or remove a POSIX lock on an open file descriptor.
9367
9368[clinic start generated code]*/
9369
Larry Hastings2f936352014-08-05 14:04:04 +10009370static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009371os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
9372/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009373{
9374 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009375
Saiyang Gou7514f4f2020-02-12 23:47:42 -08009376 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
9377 return NULL;
9378 }
9379
Ross Lagerwall7807c352011-03-17 20:20:30 +02009380 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009381 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009382 Py_END_ALLOW_THREADS
9383
9384 if (res < 0)
9385 return posix_error();
9386
9387 Py_RETURN_NONE;
9388}
Larry Hastings2f936352014-08-05 14:04:04 +10009389#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009391
Larry Hastings2f936352014-08-05 14:04:04 +10009392/*[clinic input]
9393os.lseek -> Py_off_t
9394
9395 fd: int
9396 position: Py_off_t
9397 how: int
9398 /
9399
9400Set the position of a file descriptor. Return the new position.
9401
9402Return the new cursor position in number of bytes
9403relative to the beginning of the file.
9404[clinic start generated code]*/
9405
Larry Hastings2f936352014-08-05 14:04:04 +10009406static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009407os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
9408/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009409{
9410 Py_off_t result;
9411
Guido van Rossum687dd131993-05-17 08:34:16 +00009412#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00009413 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
9414 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10009415 case 0: how = SEEK_SET; break;
9416 case 1: how = SEEK_CUR; break;
9417 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00009418 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009419#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009420
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009422 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02009423#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009424 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009425#else
Larry Hastings2f936352014-08-05 14:04:04 +10009426 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009427#endif
Steve Dower8fc89802015-04-12 00:26:27 -04009428 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009429 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009430 if (result < 0)
9431 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00009432
Larry Hastings2f936352014-08-05 14:04:04 +10009433 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00009434}
9435
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009436
Larry Hastings2f936352014-08-05 14:04:04 +10009437/*[clinic input]
9438os.read
9439 fd: int
9440 length: Py_ssize_t
9441 /
9442
9443Read from a file descriptor. Returns a bytes object.
9444[clinic start generated code]*/
9445
Larry Hastings2f936352014-08-05 14:04:04 +10009446static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009447os_read_impl(PyObject *module, int fd, Py_ssize_t length)
9448/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009449{
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 Py_ssize_t n;
9451 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10009452
9453 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 errno = EINVAL;
9455 return posix_error();
9456 }
Larry Hastings2f936352014-08-05 14:04:04 +10009457
Victor Stinner9a0d7a72018-11-22 15:03:40 +01009458 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10009459
9460 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00009461 if (buffer == NULL)
9462 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009463
Victor Stinner66aab0c2015-03-19 22:53:20 +01009464 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
9465 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01009467 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009468 }
Larry Hastings2f936352014-08-05 14:04:04 +10009469
9470 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00009471 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10009472
Victor Stinner8c62be82010-05-06 00:08:46 +00009473 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00009474}
9475
Ross Lagerwall7807c352011-03-17 20:20:30 +02009476#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009477 || defined(__APPLE__))) \
9478 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9479 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9480static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009481iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009482{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009483 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009484
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009485 *iov = PyMem_New(struct iovec, cnt);
9486 if (*iov == NULL) {
9487 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009488 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009489 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009490
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009491 *buf = PyMem_New(Py_buffer, cnt);
9492 if (*buf == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01009493 PyMem_Free(*iov);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009494 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009495 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009496 }
9497
9498 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009499 PyObject *item = PySequence_GetItem(seq, i);
9500 if (item == NULL)
9501 goto fail;
9502 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9503 Py_DECREF(item);
9504 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009505 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009506 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009507 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009508 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009509 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009510 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009511
9512fail:
Victor Stinner00d7abd2020-12-01 09:56:42 +01009513 PyMem_Free(*iov);
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009514 for (j = 0; j < i; j++) {
9515 PyBuffer_Release(&(*buf)[j]);
9516 }
Victor Stinner00d7abd2020-12-01 09:56:42 +01009517 PyMem_Free(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009518 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009519}
9520
9521static void
9522iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9523{
9524 int i;
Victor Stinner00d7abd2020-12-01 09:56:42 +01009525 PyMem_Free(iov);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009526 for (i = 0; i < cnt; i++) {
9527 PyBuffer_Release(&buf[i]);
9528 }
Victor Stinner00d7abd2020-12-01 09:56:42 +01009529 PyMem_Free(buf);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009530}
9531#endif
9532
Larry Hastings2f936352014-08-05 14:04:04 +10009533
Ross Lagerwall7807c352011-03-17 20:20:30 +02009534#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009535/*[clinic input]
9536os.readv -> Py_ssize_t
9537
9538 fd: int
9539 buffers: object
9540 /
9541
9542Read from a file descriptor fd into an iterable of buffers.
9543
9544The buffers should be mutable buffers accepting bytes.
9545readv will transfer data into each buffer until it is full
9546and then move on to the next buffer in the sequence to hold
9547the rest of the data.
9548
9549readv returns the total number of bytes read,
9550which may be less than the total capacity of all the buffers.
9551[clinic start generated code]*/
9552
Larry Hastings2f936352014-08-05 14:04:04 +10009553static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009554os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9555/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009556{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009557 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009558 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009559 struct iovec *iov;
9560 Py_buffer *buf;
9561
Larry Hastings2f936352014-08-05 14:04:04 +10009562 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009563 PyErr_SetString(PyExc_TypeError,
9564 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009565 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009566 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009567
Larry Hastings2f936352014-08-05 14:04:04 +10009568 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009569 if (cnt < 0)
9570 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009571
9572 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9573 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009574
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009575 do {
9576 Py_BEGIN_ALLOW_THREADS
9577 n = readv(fd, iov, cnt);
9578 Py_END_ALLOW_THREADS
9579 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009580
9581 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009582 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009583 if (!async_err)
9584 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009585 return -1;
9586 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009587
Larry Hastings2f936352014-08-05 14:04:04 +10009588 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009589}
Larry Hastings2f936352014-08-05 14:04:04 +10009590#endif /* HAVE_READV */
9591
Ross Lagerwall7807c352011-03-17 20:20:30 +02009592
9593#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009594/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009595os.pread
9596
9597 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009598 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009599 offset: Py_off_t
9600 /
9601
9602Read a number of bytes from a file descriptor starting at a particular offset.
9603
9604Read length bytes from file descriptor fd, starting at offset bytes from
9605the beginning of the file. The file offset remains unchanged.
9606[clinic start generated code]*/
9607
Larry Hastings2f936352014-08-05 14:04:04 +10009608static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009609os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9610/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009611{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009612 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009613 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009614 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009615
Larry Hastings2f936352014-08-05 14:04:04 +10009616 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009617 errno = EINVAL;
9618 return posix_error();
9619 }
Larry Hastings2f936352014-08-05 14:04:04 +10009620 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009621 if (buffer == NULL)
9622 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009623
9624 do {
9625 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009626 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009627 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009628 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009629 Py_END_ALLOW_THREADS
9630 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9631
Ross Lagerwall7807c352011-03-17 20:20:30 +02009632 if (n < 0) {
9633 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009634 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009635 }
Larry Hastings2f936352014-08-05 14:04:04 +10009636 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009637 _PyBytes_Resize(&buffer, n);
9638 return buffer;
9639}
Larry Hastings2f936352014-08-05 14:04:04 +10009640#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009641
Pablo Galindo4defba32018-01-27 16:16:37 +00009642#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9643/*[clinic input]
9644os.preadv -> Py_ssize_t
9645
9646 fd: int
9647 buffers: object
9648 offset: Py_off_t
9649 flags: int = 0
9650 /
9651
9652Reads from a file descriptor into a number of mutable bytes-like objects.
9653
9654Combines the functionality of readv() and pread(). As readv(), it will
9655transfer data into each buffer until it is full and then move on to the next
9656buffer in the sequence to hold the rest of the data. Its fourth argument,
9657specifies the file offset at which the input operation is to be performed. It
9658will return the total number of bytes read (which can be less than the total
9659capacity of all the objects).
9660
9661The flags argument contains a bitwise OR of zero or more of the following flags:
9662
9663- RWF_HIPRI
9664- RWF_NOWAIT
9665
9666Using non-zero flags requires Linux 4.6 or newer.
9667[clinic start generated code]*/
9668
9669static Py_ssize_t
9670os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9671 int flags)
9672/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9673{
9674 Py_ssize_t cnt, n;
9675 int async_err = 0;
9676 struct iovec *iov;
9677 Py_buffer *buf;
9678
9679 if (!PySequence_Check(buffers)) {
9680 PyErr_SetString(PyExc_TypeError,
9681 "preadv2() arg 2 must be a sequence");
9682 return -1;
9683 }
9684
9685 cnt = PySequence_Size(buffers);
9686 if (cnt < 0) {
9687 return -1;
9688 }
9689
9690#ifndef HAVE_PREADV2
9691 if(flags != 0) {
9692 argument_unavailable_error("preadv2", "flags");
9693 return -1;
9694 }
9695#endif
9696
9697 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9698 return -1;
9699 }
9700#ifdef HAVE_PREADV2
9701 do {
9702 Py_BEGIN_ALLOW_THREADS
9703 _Py_BEGIN_SUPPRESS_IPH
9704 n = preadv2(fd, iov, cnt, offset, flags);
9705 _Py_END_SUPPRESS_IPH
9706 Py_END_ALLOW_THREADS
9707 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9708#else
9709 do {
Ronald Oussoren41761932020-11-08 10:05:27 +01009710#ifdef __APPLE__
9711/* This entire function will be removed from the module dict when the API
9712 * is not available.
9713 */
9714#pragma clang diagnostic push
9715#pragma clang diagnostic ignored "-Wunguarded-availability"
9716#pragma clang diagnostic ignored "-Wunguarded-availability-new"
9717#endif
Pablo Galindo4defba32018-01-27 16:16:37 +00009718 Py_BEGIN_ALLOW_THREADS
9719 _Py_BEGIN_SUPPRESS_IPH
9720 n = preadv(fd, iov, cnt, offset);
9721 _Py_END_SUPPRESS_IPH
9722 Py_END_ALLOW_THREADS
9723 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +01009724
9725#ifdef __APPLE__
9726#pragma clang diagnostic pop
9727#endif
9728
Pablo Galindo4defba32018-01-27 16:16:37 +00009729#endif
9730
9731 iov_cleanup(iov, buf, cnt);
9732 if (n < 0) {
9733 if (!async_err) {
9734 posix_error();
9735 }
9736 return -1;
9737 }
9738
9739 return n;
9740}
9741#endif /* HAVE_PREADV */
9742
Larry Hastings2f936352014-08-05 14:04:04 +10009743
9744/*[clinic input]
9745os.write -> Py_ssize_t
9746
9747 fd: int
9748 data: Py_buffer
9749 /
9750
9751Write a bytes object to a file descriptor.
9752[clinic start generated code]*/
9753
Larry Hastings2f936352014-08-05 14:04:04 +10009754static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009755os_write_impl(PyObject *module, int fd, Py_buffer *data)
9756/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009757{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009758 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009759}
9760
9761#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009762#ifdef __APPLE__
9763/*[clinic input]
9764os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009765
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009766 out_fd: int
9767 in_fd: int
9768 offset: Py_off_t
9769 count as sbytes: Py_off_t
9770 headers: object(c_default="NULL") = ()
9771 trailers: object(c_default="NULL") = ()
9772 flags: int = 0
9773
9774Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9775[clinic start generated code]*/
9776
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009777static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009778os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9779 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9780 int flags)
9781/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9782#elif defined(__FreeBSD__) || defined(__DragonFly__)
9783/*[clinic input]
9784os.sendfile
9785
9786 out_fd: int
9787 in_fd: int
9788 offset: Py_off_t
9789 count: Py_ssize_t
9790 headers: object(c_default="NULL") = ()
9791 trailers: object(c_default="NULL") = ()
9792 flags: int = 0
9793
9794Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9795[clinic start generated code]*/
9796
9797static PyObject *
9798os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9799 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9800 int flags)
9801/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9802#else
9803/*[clinic input]
9804os.sendfile
9805
9806 out_fd: int
9807 in_fd: int
9808 offset as offobj: object
9809 count: Py_ssize_t
9810
9811Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9812[clinic start generated code]*/
9813
9814static PyObject *
9815os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9816 Py_ssize_t count)
9817/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9818#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009819{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009820 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009821 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009822
9823#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9824#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009825 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009826#endif
9827 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009828 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009829
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009830 sf.headers = NULL;
9831 sf.trailers = NULL;
9832
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009833 if (headers != NULL) {
9834 if (!PySequence_Check(headers)) {
9835 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009836 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009837 return NULL;
9838 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009839 Py_ssize_t i = PySequence_Size(headers);
9840 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009841 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009842 if (i > INT_MAX) {
9843 PyErr_SetString(PyExc_OverflowError,
9844 "sendfile() header is too large");
9845 return NULL;
9846 }
9847 if (i > 0) {
9848 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009849 if (iov_setup(&(sf.headers), &hbuf,
9850 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009851 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009852#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009853 for (i = 0; i < sf.hdr_cnt; i++) {
9854 Py_ssize_t blen = sf.headers[i].iov_len;
9855# define OFF_T_MAX 0x7fffffffffffffff
9856 if (sbytes >= OFF_T_MAX - blen) {
9857 PyErr_SetString(PyExc_OverflowError,
9858 "sendfile() header is too large");
9859 return NULL;
9860 }
9861 sbytes += blen;
9862 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009863#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009864 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009865 }
9866 }
9867 if (trailers != NULL) {
9868 if (!PySequence_Check(trailers)) {
9869 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009870 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009871 return NULL;
9872 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009873 Py_ssize_t i = PySequence_Size(trailers);
9874 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009875 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009876 if (i > INT_MAX) {
9877 PyErr_SetString(PyExc_OverflowError,
9878 "sendfile() trailer is too large");
9879 return NULL;
9880 }
9881 if (i > 0) {
9882 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009883 if (iov_setup(&(sf.trailers), &tbuf,
9884 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009885 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009886 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009887 }
9888 }
9889
Steve Dower8fc89802015-04-12 00:26:27 -04009890 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009891 do {
9892 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009893#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009894 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009895#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009896 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009897#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009898 Py_END_ALLOW_THREADS
9899 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009900 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009901
9902 if (sf.headers != NULL)
9903 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9904 if (sf.trailers != NULL)
9905 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9906
9907 if (ret < 0) {
9908 if ((errno == EAGAIN) || (errno == EBUSY)) {
9909 if (sbytes != 0) {
9910 // some data has been sent
9911 goto done;
9912 }
9913 else {
9914 // no data has been sent; upper application is supposed
9915 // to retry on EAGAIN or EBUSY
9916 return posix_error();
9917 }
9918 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009919 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009920 }
9921 goto done;
9922
9923done:
9924 #if !defined(HAVE_LARGEFILE_SUPPORT)
9925 return Py_BuildValue("l", sbytes);
9926 #else
9927 return Py_BuildValue("L", sbytes);
9928 #endif
9929
9930#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009931#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009932 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009933 do {
9934 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009935 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009936 Py_END_ALLOW_THREADS
9937 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009938 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009939 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009940 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009941 }
9942#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009943 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009944 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009945 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009946
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009947#if defined(__sun) && defined(__SVR4)
9948 // On Solaris, sendfile raises EINVAL rather than returning 0
9949 // when the offset is equal or bigger than the in_fd size.
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009950 struct stat st;
9951
9952 do {
9953 Py_BEGIN_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009954 ret = fstat(in_fd, &st);
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009955 Py_END_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009956 } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009957 if (ret < 0)
9958 return (!async_err) ? posix_error() : NULL;
9959
9960 if (offset >= st.st_size) {
9961 return Py_BuildValue("i", 0);
9962 }
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009963
9964 // On illumos specifically sendfile() may perform a partial write but
9965 // return -1/an error (in one confirmed case the destination socket
9966 // had a 5 second timeout set and errno was EAGAIN) and it's on the client
9967 // code to check if the offset parameter was modified by sendfile().
9968 //
9969 // We need this variable to track said change.
9970 off_t original_offset = offset;
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009971#endif
9972
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009973 do {
9974 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009975 ret = sendfile(out_fd, in_fd, &offset, count);
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009976#if defined(__sun) && defined(__SVR4)
9977 // This handles illumos-specific sendfile() partial write behavior,
9978 // see a comment above for more details.
9979 if (ret < 0 && offset != original_offset) {
9980 ret = offset - original_offset;
9981 }
9982#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009983 Py_END_ALLOW_THREADS
9984 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009985 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009986 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009987 return Py_BuildValue("n", ret);
9988#endif
9989}
Larry Hastings2f936352014-08-05 14:04:04 +10009990#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009991
Larry Hastings2f936352014-08-05 14:04:04 +10009992
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009993#if defined(__APPLE__)
9994/*[clinic input]
9995os._fcopyfile
9996
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009997 in_fd: int
9998 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009999 flags: int
10000 /
10001
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -070010002Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020010003[clinic start generated code]*/
10004
10005static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +030010006os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
10007/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020010008{
10009 int ret;
10010
10011 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +030010012 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020010013 Py_END_ALLOW_THREADS
10014 if (ret < 0)
10015 return posix_error();
10016 Py_RETURN_NONE;
10017}
10018#endif
10019
10020
Larry Hastings2f936352014-08-05 14:04:04 +100010021/*[clinic input]
10022os.fstat
10023
10024 fd : int
10025
10026Perform a stat system call on the given file descriptor.
10027
10028Like stat(), but for an open file descriptor.
10029Equivalent to os.stat(fd).
10030[clinic start generated code]*/
10031
Larry Hastings2f936352014-08-05 14:04:04 +100010032static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010033os_fstat_impl(PyObject *module, int fd)
10034/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010035{
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 STRUCT_STAT st;
10037 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010038 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010039
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010040 do {
10041 Py_BEGIN_ALLOW_THREADS
10042 res = FSTAT(fd, &st);
10043 Py_END_ALLOW_THREADS
10044 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +000010046#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +010010047 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +000010048#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010049 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +000010050#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 }
Tim Peters5aa91602002-01-30 05:46:57 +000010052
Victor Stinner1c2fa782020-05-10 11:05:29 +020010053 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +000010054}
10055
Larry Hastings2f936352014-08-05 14:04:04 +100010056
10057/*[clinic input]
10058os.isatty -> bool
10059 fd: int
10060 /
10061
10062Return True if the fd is connected to a terminal.
10063
10064Return True if the file descriptor is an open file descriptor
10065connected to the slave end of a terminal.
10066[clinic start generated code]*/
10067
Larry Hastings2f936352014-08-05 14:04:04 +100010068static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010069os_isatty_impl(PyObject *module, int fd)
10070/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010071{
Steve Dower8fc89802015-04-12 00:26:27 -040010072 int return_value;
Miss Islington (bot)23c46772021-09-09 09:35:43 -070010073 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -040010074 _Py_BEGIN_SUPPRESS_IPH
10075 return_value = isatty(fd);
10076 _Py_END_SUPPRESS_IPH
Miss Islington (bot)23c46772021-09-09 09:35:43 -070010077 Py_END_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -040010078 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100010079}
10080
10081
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010082#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +100010083/*[clinic input]
10084os.pipe
10085
10086Create a pipe.
10087
10088Returns a tuple of two file descriptors:
10089 (read_fd, write_fd)
10090[clinic start generated code]*/
10091
Larry Hastings2f936352014-08-05 14:04:04 +100010092static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010093os_pipe_impl(PyObject *module)
10094/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +000010095{
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +020010097#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010099 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010101#else
10102 int res;
10103#endif
10104
10105#ifdef MS_WINDOWS
10106 attr.nLength = sizeof(attr);
10107 attr.lpSecurityDescriptor = NULL;
10108 attr.bInheritHandle = FALSE;
10109
10110 Py_BEGIN_ALLOW_THREADS
10111 ok = CreatePipe(&read, &write, &attr, 0);
10112 if (ok) {
Segev Finer5e437fb2021-04-24 01:00:27 +030010113 fds[0] = _Py_open_osfhandle_noraise(read, _O_RDONLY);
10114 fds[1] = _Py_open_osfhandle_noraise(write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010115 if (fds[0] == -1 || fds[1] == -1) {
10116 CloseHandle(read);
10117 CloseHandle(write);
10118 ok = 0;
10119 }
10120 }
10121 Py_END_ALLOW_THREADS
10122
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +010010124 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010125#else
10126
10127#ifdef HAVE_PIPE2
10128 Py_BEGIN_ALLOW_THREADS
10129 res = pipe2(fds, O_CLOEXEC);
10130 Py_END_ALLOW_THREADS
10131
10132 if (res != 0 && errno == ENOSYS)
10133 {
10134#endif
10135 Py_BEGIN_ALLOW_THREADS
10136 res = pipe(fds);
10137 Py_END_ALLOW_THREADS
10138
10139 if (res == 0) {
10140 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
10141 close(fds[0]);
10142 close(fds[1]);
10143 return NULL;
10144 }
10145 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
10146 close(fds[0]);
10147 close(fds[1]);
10148 return NULL;
10149 }
10150 }
10151#ifdef HAVE_PIPE2
10152 }
10153#endif
10154
10155 if (res != 0)
10156 return PyErr_SetFromErrno(PyExc_OSError);
10157#endif /* !MS_WINDOWS */
10158 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +000010159}
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010160#endif /* HAVE_PIPE */
10161
Larry Hastings2f936352014-08-05 14:04:04 +100010162
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010163#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +100010164/*[clinic input]
10165os.pipe2
10166
10167 flags: int
10168 /
10169
10170Create a pipe with flags set atomically.
10171
10172Returns a tuple of two file descriptors:
10173 (read_fd, write_fd)
10174
10175flags can be constructed by ORing together one or more of these values:
10176O_NONBLOCK, O_CLOEXEC.
10177[clinic start generated code]*/
10178
Larry Hastings2f936352014-08-05 14:04:04 +100010179static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010180os_pipe2_impl(PyObject *module, int flags)
10181/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010182{
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010183 int fds[2];
10184 int res;
10185
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010186 res = pipe2(fds, flags);
10187 if (res != 0)
10188 return posix_error();
10189 return Py_BuildValue("(ii)", fds[0], fds[1]);
10190}
10191#endif /* HAVE_PIPE2 */
10192
Larry Hastings2f936352014-08-05 14:04:04 +100010193
Ross Lagerwall7807c352011-03-17 20:20:30 +020010194#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +100010195/*[clinic input]
10196os.writev -> Py_ssize_t
10197 fd: int
10198 buffers: object
10199 /
10200
10201Iterate over buffers, and write the contents of each to a file descriptor.
10202
10203Returns the total number of bytes written.
10204buffers must be a sequence of bytes-like objects.
10205[clinic start generated code]*/
10206
Larry Hastings2f936352014-08-05 14:04:04 +100010207static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010208os_writev_impl(PyObject *module, int fd, PyObject *buffers)
10209/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010210{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010211 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +100010212 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010213 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010214 struct iovec *iov;
10215 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +100010216
10217 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020010218 PyErr_SetString(PyExc_TypeError,
10219 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +100010220 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010221 }
Larry Hastings2f936352014-08-05 14:04:04 +100010222 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010223 if (cnt < 0)
10224 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010225
Larry Hastings2f936352014-08-05 14:04:04 +100010226 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10227 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010228 }
10229
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010230 do {
10231 Py_BEGIN_ALLOW_THREADS
10232 result = writev(fd, iov, cnt);
10233 Py_END_ALLOW_THREADS
10234 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +020010235
10236 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010237 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010238 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +010010239
Georg Brandl306336b2012-06-24 12:55:33 +020010240 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010241}
Larry Hastings2f936352014-08-05 14:04:04 +100010242#endif /* HAVE_WRITEV */
10243
10244
10245#ifdef HAVE_PWRITE
10246/*[clinic input]
10247os.pwrite -> Py_ssize_t
10248
10249 fd: int
10250 buffer: Py_buffer
10251 offset: Py_off_t
10252 /
10253
10254Write bytes to a file descriptor starting at a particular offset.
10255
10256Write buffer to fd, starting at offset bytes from the beginning of
10257the file. Returns the number of bytes writte. Does not change the
10258current file offset.
10259[clinic start generated code]*/
10260
Larry Hastings2f936352014-08-05 14:04:04 +100010261static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010262os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
10263/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010264{
10265 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010266 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010267
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010268 do {
10269 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -040010270 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010271 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -040010272 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010273 Py_END_ALLOW_THREADS
10274 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010275
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010276 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010277 posix_error();
10278 return size;
10279}
10280#endif /* HAVE_PWRITE */
10281
Pablo Galindo4defba32018-01-27 16:16:37 +000010282#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
10283/*[clinic input]
10284os.pwritev -> Py_ssize_t
10285
10286 fd: int
10287 buffers: object
10288 offset: Py_off_t
10289 flags: int = 0
10290 /
10291
10292Writes the contents of bytes-like objects to a file descriptor at a given offset.
10293
10294Combines the functionality of writev() and pwrite(). All buffers must be a sequence
10295of bytes-like objects. Buffers are processed in array order. Entire contents of first
10296buffer is written before proceeding to second, and so on. The operating system may
10297set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
10298This function writes the contents of each object to the file descriptor and returns
10299the total number of bytes written.
10300
10301The flags argument contains a bitwise OR of zero or more of the following flags:
10302
10303- RWF_DSYNC
10304- RWF_SYNC
YoSTEALTH76ef2552020-05-27 15:32:22 -060010305- RWF_APPEND
Pablo Galindo4defba32018-01-27 16:16:37 +000010306
10307Using non-zero flags requires Linux 4.7 or newer.
10308[clinic start generated code]*/
10309
10310static Py_ssize_t
10311os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
10312 int flags)
YoSTEALTH76ef2552020-05-27 15:32:22 -060010313/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/
Pablo Galindo4defba32018-01-27 16:16:37 +000010314{
10315 Py_ssize_t cnt;
10316 Py_ssize_t result;
10317 int async_err = 0;
10318 struct iovec *iov;
10319 Py_buffer *buf;
10320
10321 if (!PySequence_Check(buffers)) {
10322 PyErr_SetString(PyExc_TypeError,
10323 "pwritev() arg 2 must be a sequence");
10324 return -1;
10325 }
10326
10327 cnt = PySequence_Size(buffers);
10328 if (cnt < 0) {
10329 return -1;
10330 }
10331
10332#ifndef HAVE_PWRITEV2
10333 if(flags != 0) {
10334 argument_unavailable_error("pwritev2", "flags");
10335 return -1;
10336 }
10337#endif
10338
10339 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10340 return -1;
10341 }
10342#ifdef HAVE_PWRITEV2
10343 do {
10344 Py_BEGIN_ALLOW_THREADS
10345 _Py_BEGIN_SUPPRESS_IPH
10346 result = pwritev2(fd, iov, cnt, offset, flags);
10347 _Py_END_SUPPRESS_IPH
10348 Py_END_ALLOW_THREADS
10349 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10350#else
Ronald Oussoren41761932020-11-08 10:05:27 +010010351
10352#ifdef __APPLE__
10353/* This entire function will be removed from the module dict when the API
10354 * is not available.
10355 */
10356#pragma clang diagnostic push
10357#pragma clang diagnostic ignored "-Wunguarded-availability"
10358#pragma clang diagnostic ignored "-Wunguarded-availability-new"
10359#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000010360 do {
10361 Py_BEGIN_ALLOW_THREADS
10362 _Py_BEGIN_SUPPRESS_IPH
10363 result = pwritev(fd, iov, cnt, offset);
10364 _Py_END_SUPPRESS_IPH
10365 Py_END_ALLOW_THREADS
10366 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +010010367
10368#ifdef __APPLE__
10369#pragma clang diagnostic pop
10370#endif
10371
Pablo Galindo4defba32018-01-27 16:16:37 +000010372#endif
10373
10374 iov_cleanup(iov, buf, cnt);
10375 if (result < 0) {
10376 if (!async_err) {
10377 posix_error();
10378 }
10379 return -1;
10380 }
10381
10382 return result;
10383}
10384#endif /* HAVE_PWRITEV */
10385
Pablo Galindoaac4d032019-05-31 19:39:47 +010010386#ifdef HAVE_COPY_FILE_RANGE
10387/*[clinic input]
10388
10389os.copy_file_range
10390 src: int
10391 Source file descriptor.
10392 dst: int
10393 Destination file descriptor.
10394 count: Py_ssize_t
10395 Number of bytes to copy.
10396 offset_src: object = None
10397 Starting offset in src.
10398 offset_dst: object = None
10399 Starting offset in dst.
10400
10401Copy count bytes from one file descriptor to another.
10402
10403If offset_src is None, then src is read from the current position;
10404respectively for offset_dst.
10405[clinic start generated code]*/
10406
10407static PyObject *
10408os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10409 PyObject *offset_src, PyObject *offset_dst)
10410/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
10411{
10412 off_t offset_src_val, offset_dst_val;
10413 off_t *p_offset_src = NULL;
10414 off_t *p_offset_dst = NULL;
10415 Py_ssize_t ret;
10416 int async_err = 0;
10417 /* The flags argument is provided to allow
10418 * for future extensions and currently must be to 0. */
10419 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +000010420
10421
Pablo Galindoaac4d032019-05-31 19:39:47 +010010422 if (count < 0) {
10423 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10424 return NULL;
10425 }
10426
10427 if (offset_src != Py_None) {
10428 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10429 return NULL;
10430 }
10431 p_offset_src = &offset_src_val;
10432 }
10433
10434 if (offset_dst != Py_None) {
10435 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10436 return NULL;
10437 }
10438 p_offset_dst = &offset_dst_val;
10439 }
10440
10441 do {
10442 Py_BEGIN_ALLOW_THREADS
10443 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
10444 Py_END_ALLOW_THREADS
10445 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10446
10447 if (ret < 0) {
10448 return (!async_err) ? posix_error() : NULL;
10449 }
10450
10451 return PyLong_FromSsize_t(ret);
10452}
10453#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +100010454
Pablo Galindodedc2cd2020-12-02 17:57:18 +000010455#if (defined(HAVE_SPLICE) && !defined(_AIX))
Pablo Galindoa57b3d32020-11-17 00:00:38 +000010456/*[clinic input]
10457
10458os.splice
10459 src: int
10460 Source file descriptor.
10461 dst: int
10462 Destination file descriptor.
10463 count: Py_ssize_t
10464 Number of bytes to copy.
10465 offset_src: object = None
10466 Starting offset in src.
10467 offset_dst: object = None
10468 Starting offset in dst.
10469 flags: unsigned_int = 0
10470 Flags to modify the semantics of the call.
10471
10472Transfer count bytes from one pipe to a descriptor or vice versa.
10473
10474If offset_src is None, then src is read from the current position;
10475respectively for offset_dst. The offset associated to the file
10476descriptor that refers to a pipe must be None.
10477[clinic start generated code]*/
10478
10479static PyObject *
10480os_splice_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10481 PyObject *offset_src, PyObject *offset_dst,
10482 unsigned int flags)
10483/*[clinic end generated code: output=d0386f25a8519dc5 input=047527c66c6d2e0a]*/
10484{
10485 off_t offset_src_val, offset_dst_val;
10486 off_t *p_offset_src = NULL;
10487 off_t *p_offset_dst = NULL;
10488 Py_ssize_t ret;
10489 int async_err = 0;
10490
10491 if (count < 0) {
10492 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10493 return NULL;
10494 }
10495
10496 if (offset_src != Py_None) {
10497 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10498 return NULL;
10499 }
10500 p_offset_src = &offset_src_val;
10501 }
10502
10503 if (offset_dst != Py_None) {
10504 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10505 return NULL;
10506 }
10507 p_offset_dst = &offset_dst_val;
10508 }
10509
10510 do {
10511 Py_BEGIN_ALLOW_THREADS
10512 ret = splice(src, p_offset_src, dst, p_offset_dst, count, flags);
10513 Py_END_ALLOW_THREADS
10514 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10515
10516 if (ret < 0) {
10517 return (!async_err) ? posix_error() : NULL;
10518 }
10519
10520 return PyLong_FromSsize_t(ret);
10521}
10522#endif /* HAVE_SPLICE*/
10523
Larry Hastings2f936352014-08-05 14:04:04 +100010524#ifdef HAVE_MKFIFO
10525/*[clinic input]
10526os.mkfifo
10527
10528 path: path_t
10529 mode: int=0o666
10530 *
10531 dir_fd: dir_fd(requires='mkfifoat')=None
10532
10533Create a "fifo" (a POSIX named pipe).
10534
10535If dir_fd is not None, it should be a file descriptor open to a directory,
10536 and path should be relative; path will then be relative to that directory.
10537dir_fd may not be implemented on your platform.
10538 If it is unavailable, using it will raise a NotImplementedError.
10539[clinic start generated code]*/
10540
Larry Hastings2f936352014-08-05 14:04:04 +100010541static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010542os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
10543/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010544{
10545 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010546 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010547
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010548 do {
10549 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010550#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010551 if (dir_fd != DEFAULT_DIR_FD)
10552 result = mkfifoat(dir_fd, path->narrow, mode);
10553 else
Ross Lagerwall7807c352011-03-17 20:20:30 +020010554#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010555 result = mkfifo(path->narrow, mode);
10556 Py_END_ALLOW_THREADS
10557 } while (result != 0 && errno == EINTR &&
10558 !(async_err = PyErr_CheckSignals()));
10559 if (result != 0)
10560 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010561
10562 Py_RETURN_NONE;
10563}
10564#endif /* HAVE_MKFIFO */
10565
10566
10567#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
10568/*[clinic input]
10569os.mknod
10570
10571 path: path_t
10572 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010573 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +100010574 *
10575 dir_fd: dir_fd(requires='mknodat')=None
10576
10577Create a node in the file system.
10578
10579Create a node in the file system (file, device special file or named pipe)
10580at path. mode specifies both the permissions to use and the
10581type of node to be created, being combined (bitwise OR) with one of
10582S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
10583device defines the newly created device special file (probably using
10584os.makedev()). Otherwise device is ignored.
10585
10586If dir_fd is not None, it should be a file descriptor open to a directory,
10587 and path should be relative; path will then be relative to that directory.
10588dir_fd may not be implemented on your platform.
10589 If it is unavailable, using it will raise a NotImplementedError.
10590[clinic start generated code]*/
10591
Larry Hastings2f936352014-08-05 14:04:04 +100010592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010593os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -040010594 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010595/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010596{
10597 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010598 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010599
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010600 do {
10601 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010602#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010603 if (dir_fd != DEFAULT_DIR_FD)
10604 result = mknodat(dir_fd, path->narrow, mode, device);
10605 else
Larry Hastings2f936352014-08-05 14:04:04 +100010606#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010607 result = mknod(path->narrow, mode, device);
10608 Py_END_ALLOW_THREADS
10609 } while (result != 0 && errno == EINTR &&
10610 !(async_err = PyErr_CheckSignals()));
10611 if (result != 0)
10612 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010613
10614 Py_RETURN_NONE;
10615}
10616#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10617
10618
10619#ifdef HAVE_DEVICE_MACROS
10620/*[clinic input]
10621os.major -> unsigned_int
10622
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010623 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010624 /
10625
10626Extracts a device major number from a raw device number.
10627[clinic start generated code]*/
10628
Larry Hastings2f936352014-08-05 14:04:04 +100010629static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010630os_major_impl(PyObject *module, dev_t device)
10631/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010632{
10633 return major(device);
10634}
10635
10636
10637/*[clinic input]
10638os.minor -> unsigned_int
10639
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010640 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010641 /
10642
10643Extracts a device minor number from a raw device number.
10644[clinic start generated code]*/
10645
Larry Hastings2f936352014-08-05 14:04:04 +100010646static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010647os_minor_impl(PyObject *module, dev_t device)
10648/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010649{
10650 return minor(device);
10651}
10652
10653
10654/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010655os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010656
10657 major: int
10658 minor: int
10659 /
10660
10661Composes a raw device number from the major and minor device numbers.
10662[clinic start generated code]*/
10663
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010664static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010665os_makedev_impl(PyObject *module, int major, int minor)
10666/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010667{
10668 return makedev(major, minor);
10669}
10670#endif /* HAVE_DEVICE_MACROS */
10671
10672
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010673#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010674/*[clinic input]
10675os.ftruncate
10676
10677 fd: int
10678 length: Py_off_t
10679 /
10680
10681Truncate a file, specified by file descriptor, to a specific length.
10682[clinic start generated code]*/
10683
Larry Hastings2f936352014-08-05 14:04:04 +100010684static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010685os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10686/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010687{
10688 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010689 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010690
Steve Dowerb82e17e2019-05-23 08:45:22 -070010691 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10692 return NULL;
10693 }
10694
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010695 do {
10696 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010697 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010698#ifdef MS_WINDOWS
10699 result = _chsize_s(fd, length);
10700#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010701 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010702#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010703 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010704 Py_END_ALLOW_THREADS
10705 } while (result != 0 && errno == EINTR &&
10706 !(async_err = PyErr_CheckSignals()));
10707 if (result != 0)
10708 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010709 Py_RETURN_NONE;
10710}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010711#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010712
10713
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010714#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010715/*[clinic input]
10716os.truncate
10717 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10718 length: Py_off_t
10719
10720Truncate a file, specified by path, to a specific length.
10721
10722On some platforms, path may also be specified as an open file descriptor.
10723 If this functionality is unavailable, using it raises an exception.
10724[clinic start generated code]*/
10725
Larry Hastings2f936352014-08-05 14:04:04 +100010726static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010727os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10728/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010729{
10730 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010731#ifdef MS_WINDOWS
10732 int fd;
10733#endif
10734
10735 if (path->fd != -1)
10736 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010737
Steve Dowerb82e17e2019-05-23 08:45:22 -070010738 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10739 return NULL;
10740 }
10741
Larry Hastings2f936352014-08-05 14:04:04 +100010742 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010743 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010744#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010745 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010746 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010747 result = -1;
10748 else {
10749 result = _chsize_s(fd, length);
10750 close(fd);
10751 if (result < 0)
10752 errno = result;
10753 }
10754#else
10755 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010756#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010757 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010758 Py_END_ALLOW_THREADS
10759 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010760 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010761
10762 Py_RETURN_NONE;
10763}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010764#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010765
Ross Lagerwall7807c352011-03-17 20:20:30 +020010766
Victor Stinnerd6b17692014-09-30 12:20:05 +020010767/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10768 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10769 defined, which is the case in Python on AIX. AIX bug report:
10770 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10771#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10772# define POSIX_FADVISE_AIX_BUG
10773#endif
10774
Victor Stinnerec39e262014-09-30 12:35:58 +020010775
Victor Stinnerd6b17692014-09-30 12:20:05 +020010776#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010777/*[clinic input]
10778os.posix_fallocate
10779
10780 fd: int
10781 offset: Py_off_t
10782 length: Py_off_t
10783 /
10784
10785Ensure a file has allocated at least a particular number of bytes on disk.
10786
10787Ensure that the file specified by fd encompasses a range of bytes
10788starting at offset bytes from the beginning and continuing for length bytes.
10789[clinic start generated code]*/
10790
Larry Hastings2f936352014-08-05 14:04:04 +100010791static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010792os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010793 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010794/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010795{
10796 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010797 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010798
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010799 do {
10800 Py_BEGIN_ALLOW_THREADS
10801 result = posix_fallocate(fd, offset, length);
10802 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010803 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10804
10805 if (result == 0)
10806 Py_RETURN_NONE;
10807
10808 if (async_err)
10809 return NULL;
10810
10811 errno = result;
10812 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010813}
Victor Stinnerec39e262014-09-30 12:35:58 +020010814#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010815
Ross Lagerwall7807c352011-03-17 20:20:30 +020010816
Victor Stinnerd6b17692014-09-30 12:20:05 +020010817#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010818/*[clinic input]
10819os.posix_fadvise
10820
10821 fd: int
10822 offset: Py_off_t
10823 length: Py_off_t
10824 advice: int
10825 /
10826
10827Announce an intention to access data in a specific pattern.
10828
10829Announce an intention to access data in a specific pattern, thus allowing
10830the kernel to make optimizations.
10831The advice applies to the region of the file specified by fd starting at
10832offset and continuing for length bytes.
10833advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10834POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10835POSIX_FADV_DONTNEED.
10836[clinic start generated code]*/
10837
Larry Hastings2f936352014-08-05 14:04:04 +100010838static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010839os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010840 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010841/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010842{
10843 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010844 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010845
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010846 do {
10847 Py_BEGIN_ALLOW_THREADS
10848 result = posix_fadvise(fd, offset, length, advice);
10849 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010850 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10851
10852 if (result == 0)
10853 Py_RETURN_NONE;
10854
10855 if (async_err)
10856 return NULL;
10857
10858 errno = result;
10859 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010860}
Victor Stinnerec39e262014-09-30 12:35:58 +020010861#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010863
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010864#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010865static PyObject*
10866win32_putenv(PyObject *name, PyObject *value)
10867{
10868 /* Search from index 1 because on Windows starting '=' is allowed for
10869 defining hidden environment variables. */
10870 if (PyUnicode_GET_LENGTH(name) == 0 ||
10871 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10872 {
10873 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10874 return NULL;
10875 }
10876 PyObject *unicode;
10877 if (value != NULL) {
10878 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10879 }
10880 else {
10881 unicode = PyUnicode_FromFormat("%U=", name);
10882 }
10883 if (unicode == NULL) {
10884 return NULL;
10885 }
10886
10887 Py_ssize_t size;
10888 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10889 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10890 Py_DECREF(unicode);
10891
10892 if (env == NULL) {
10893 return NULL;
10894 }
10895 if (size > _MAX_ENV) {
10896 PyErr_Format(PyExc_ValueError,
10897 "the environment variable is longer than %u characters",
10898 _MAX_ENV);
10899 PyMem_Free(env);
10900 return NULL;
10901 }
10902
10903 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10904 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10905 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10906
10907 Prefer _wputenv() to be compatible with C libraries using CRT
10908 variables and CRT functions using these variables (ex: getenv()). */
10909 int err = _wputenv(env);
10910 PyMem_Free(env);
10911
10912 if (err) {
10913 posix_error();
10914 return NULL;
10915 }
10916
10917 Py_RETURN_NONE;
10918}
10919#endif
10920
10921
10922#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010923/*[clinic input]
10924os.putenv
10925
10926 name: unicode
10927 value: unicode
10928 /
10929
10930Change or add an environment variable.
10931[clinic start generated code]*/
10932
Larry Hastings2f936352014-08-05 14:04:04 +100010933static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010934os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10935/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010936{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010937 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10938 return NULL;
10939 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010940 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010941}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010942#else
Larry Hastings2f936352014-08-05 14:04:04 +100010943/*[clinic input]
10944os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010945
Larry Hastings2f936352014-08-05 14:04:04 +100010946 name: FSConverter
10947 value: FSConverter
10948 /
10949
10950Change or add an environment variable.
10951[clinic start generated code]*/
10952
Larry Hastings2f936352014-08-05 14:04:04 +100010953static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010954os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10955/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010956{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010957 const char *name_string = PyBytes_AS_STRING(name);
10958 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010959
Serhiy Storchaka77703942017-06-25 07:33:01 +030010960 if (strchr(name_string, '=') != NULL) {
10961 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10962 return NULL;
10963 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010964
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010965 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10966 return NULL;
10967 }
10968
Victor Stinnerb477d192020-01-22 22:48:16 +010010969 if (setenv(name_string, value_string, 1)) {
10970 return posix_error();
10971 }
Larry Hastings2f936352014-08-05 14:04:04 +100010972 Py_RETURN_NONE;
10973}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010974#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010975
10976
Victor Stinner161e7b32020-01-24 11:53:44 +010010977#ifdef MS_WINDOWS
10978/*[clinic input]
10979os.unsetenv
10980 name: unicode
10981 /
10982
10983Delete an environment variable.
10984[clinic start generated code]*/
10985
10986static PyObject *
10987os_unsetenv_impl(PyObject *module, PyObject *name)
10988/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10989{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010990 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10991 return NULL;
10992 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010993 return win32_putenv(name, NULL);
10994}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010995#else
Larry Hastings2f936352014-08-05 14:04:04 +100010996/*[clinic input]
10997os.unsetenv
10998 name: FSConverter
10999 /
11000
11001Delete an environment variable.
11002[clinic start generated code]*/
11003
Larry Hastings2f936352014-08-05 14:04:04 +100011004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011005os_unsetenv_impl(PyObject *module, PyObject *name)
11006/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011007{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080011008 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
11009 return NULL;
11010 }
Victor Stinner984890f2011-11-24 13:53:38 +010011011#ifdef HAVE_BROKEN_UNSETENV
11012 unsetenv(PyBytes_AS_STRING(name));
11013#else
Victor Stinner161e7b32020-01-24 11:53:44 +010011014 int err = unsetenv(PyBytes_AS_STRING(name));
11015 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010011016 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010011017 }
Victor Stinner984890f2011-11-24 13:53:38 +010011018#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011019
Victor Stinner84ae1182010-05-06 22:05:07 +000011020 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000011021}
Victor Stinnerb8d12622020-01-24 14:05:48 +010011022#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000011023
Larry Hastings2f936352014-08-05 14:04:04 +100011024
11025/*[clinic input]
11026os.strerror
11027
11028 code: int
11029 /
11030
11031Translate an error code to a message string.
11032[clinic start generated code]*/
11033
Larry Hastings2f936352014-08-05 14:04:04 +100011034static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011035os_strerror_impl(PyObject *module, int code)
11036/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011037{
11038 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000011039 if (message == NULL) {
11040 PyErr_SetString(PyExc_ValueError,
11041 "strerror() argument out of range");
11042 return NULL;
11043 }
Victor Stinner1b579672011-12-17 05:47:23 +010011044 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000011045}
Guido van Rossumb6a47161997-09-15 22:54:34 +000011046
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011047
Guido van Rossumc9641791998-08-04 15:26:23 +000011048#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011049#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100011050/*[clinic input]
11051os.WCOREDUMP -> bool
11052
11053 status: int
11054 /
11055
11056Return True if the process returning status was dumped to a core file.
11057[clinic start generated code]*/
11058
Larry Hastings2f936352014-08-05 14:04:04 +100011059static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011060os_WCOREDUMP_impl(PyObject *module, int status)
11061/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011062{
11063 WAIT_TYPE wait_status;
11064 WAIT_STATUS_INT(wait_status) = status;
11065 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000011066}
11067#endif /* WCOREDUMP */
11068
Larry Hastings2f936352014-08-05 14:04:04 +100011069
Fred Drake106c1a02002-04-23 15:58:02 +000011070#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100011071/*[clinic input]
11072os.WIFCONTINUED -> bool
11073
11074 status: int
11075
11076Return True if a particular process was continued from a job control stop.
11077
11078Return True if the process returning status was continued from a
11079job control stop.
11080[clinic start generated code]*/
11081
Larry Hastings2f936352014-08-05 14:04:04 +100011082static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011083os_WIFCONTINUED_impl(PyObject *module, int status)
11084/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011085{
11086 WAIT_TYPE wait_status;
11087 WAIT_STATUS_INT(wait_status) = status;
11088 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000011089}
11090#endif /* WIFCONTINUED */
11091
Larry Hastings2f936352014-08-05 14:04:04 +100011092
Guido van Rossumc9641791998-08-04 15:26:23 +000011093#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100011094/*[clinic input]
11095os.WIFSTOPPED -> bool
11096
11097 status: int
11098
11099Return True if the process returning status was stopped.
11100[clinic start generated code]*/
11101
Larry Hastings2f936352014-08-05 14:04:04 +100011102static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011103os_WIFSTOPPED_impl(PyObject *module, int status)
11104/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011105{
11106 WAIT_TYPE wait_status;
11107 WAIT_STATUS_INT(wait_status) = status;
11108 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011109}
11110#endif /* WIFSTOPPED */
11111
Larry Hastings2f936352014-08-05 14:04:04 +100011112
Guido van Rossumc9641791998-08-04 15:26:23 +000011113#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100011114/*[clinic input]
11115os.WIFSIGNALED -> bool
11116
11117 status: int
11118
11119Return True if the process returning status was terminated by a signal.
11120[clinic start generated code]*/
11121
Larry Hastings2f936352014-08-05 14:04:04 +100011122static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011123os_WIFSIGNALED_impl(PyObject *module, int status)
11124/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011125{
11126 WAIT_TYPE wait_status;
11127 WAIT_STATUS_INT(wait_status) = status;
11128 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011129}
11130#endif /* WIFSIGNALED */
11131
Larry Hastings2f936352014-08-05 14:04:04 +100011132
Guido van Rossumc9641791998-08-04 15:26:23 +000011133#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100011134/*[clinic input]
11135os.WIFEXITED -> bool
11136
11137 status: int
11138
11139Return True if the process returning status exited via the exit() system call.
11140[clinic start generated code]*/
11141
Larry Hastings2f936352014-08-05 14:04:04 +100011142static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011143os_WIFEXITED_impl(PyObject *module, int status)
11144/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011145{
11146 WAIT_TYPE wait_status;
11147 WAIT_STATUS_INT(wait_status) = status;
11148 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011149}
11150#endif /* WIFEXITED */
11151
Larry Hastings2f936352014-08-05 14:04:04 +100011152
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000011153#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100011154/*[clinic input]
11155os.WEXITSTATUS -> int
11156
11157 status: int
11158
11159Return the process return code from status.
11160[clinic start generated code]*/
11161
Larry Hastings2f936352014-08-05 14:04:04 +100011162static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011163os_WEXITSTATUS_impl(PyObject *module, int status)
11164/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011165{
11166 WAIT_TYPE wait_status;
11167 WAIT_STATUS_INT(wait_status) = status;
11168 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011169}
11170#endif /* WEXITSTATUS */
11171
Larry Hastings2f936352014-08-05 14:04:04 +100011172
Guido van Rossumc9641791998-08-04 15:26:23 +000011173#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011174/*[clinic input]
11175os.WTERMSIG -> int
11176
11177 status: int
11178
11179Return the signal that terminated the process that provided the status value.
11180[clinic start generated code]*/
11181
Larry Hastings2f936352014-08-05 14:04:04 +100011182static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011183os_WTERMSIG_impl(PyObject *module, int status)
11184/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011185{
11186 WAIT_TYPE wait_status;
11187 WAIT_STATUS_INT(wait_status) = status;
11188 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011189}
11190#endif /* WTERMSIG */
11191
Larry Hastings2f936352014-08-05 14:04:04 +100011192
Guido van Rossumc9641791998-08-04 15:26:23 +000011193#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011194/*[clinic input]
11195os.WSTOPSIG -> int
11196
11197 status: int
11198
11199Return the signal that stopped the process that provided the status value.
11200[clinic start generated code]*/
11201
Larry Hastings2f936352014-08-05 14:04:04 +100011202static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011203os_WSTOPSIG_impl(PyObject *module, int status)
11204/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011205{
11206 WAIT_TYPE wait_status;
11207 WAIT_STATUS_INT(wait_status) = status;
11208 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011209}
11210#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000011211#endif /* HAVE_SYS_WAIT_H */
11212
11213
Thomas Wouters477c8d52006-05-27 19:21:47 +000011214#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000011215#ifdef _SCO_DS
11216/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
11217 needed definitions in sys/statvfs.h */
11218#define _SVID3
11219#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011220#include <sys/statvfs.h>
11221
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011222static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020011223_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
11224 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080011225 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 if (v == NULL)
11227 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011228
11229#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11231 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11232 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
11233 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
11234 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
11235 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
11236 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
11237 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
11238 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11239 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011240#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11242 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11243 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011244 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000011245 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011246 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011248 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011249 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011250 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011252 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011254 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011255 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11256 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011257#endif
Michael Felt502d5512018-01-05 13:01:58 +010011258/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
11259 * (issue #32390). */
11260#if defined(_AIX) && defined(_ALL_SOURCE)
11261 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
11262#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010011263 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010011264#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010011265 if (PyErr_Occurred()) {
11266 Py_DECREF(v);
11267 return NULL;
11268 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011269
Victor Stinner8c62be82010-05-06 00:08:46 +000011270 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011271}
11272
Larry Hastings2f936352014-08-05 14:04:04 +100011273
11274/*[clinic input]
11275os.fstatvfs
11276 fd: int
11277 /
11278
11279Perform an fstatvfs system call on the given fd.
11280
11281Equivalent to statvfs(fd).
11282[clinic start generated code]*/
11283
Larry Hastings2f936352014-08-05 14:04:04 +100011284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011285os_fstatvfs_impl(PyObject *module, int fd)
11286/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011287{
11288 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011289 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011290 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011291
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011292 do {
11293 Py_BEGIN_ALLOW_THREADS
11294 result = fstatvfs(fd, &st);
11295 Py_END_ALLOW_THREADS
11296 } while (result != 0 && errno == EINTR &&
11297 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100011298 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011299 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011300
Victor Stinner1c2fa782020-05-10 11:05:29 +020011301 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011302}
Larry Hastings2f936352014-08-05 14:04:04 +100011303#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000011304
11305
Thomas Wouters477c8d52006-05-27 19:21:47 +000011306#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000011307#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100011308/*[clinic input]
11309os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000011310
Larry Hastings2f936352014-08-05 14:04:04 +100011311 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
11312
11313Perform a statvfs system call on the given path.
11314
11315path may always be specified as a string.
11316On some platforms, path may also be specified as an open file descriptor.
11317 If this functionality is unavailable, using it raises an exception.
11318[clinic start generated code]*/
11319
Larry Hastings2f936352014-08-05 14:04:04 +100011320static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011321os_statvfs_impl(PyObject *module, path_t *path)
11322/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011323{
11324 int result;
11325 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011326
11327 Py_BEGIN_ALLOW_THREADS
11328#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100011329 if (path->fd != -1) {
Larry Hastings2f936352014-08-05 14:04:04 +100011330 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011331 }
11332 else
11333#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011334 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011335 Py_END_ALLOW_THREADS
11336
11337 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011338 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011339 }
11340
Victor Stinner1c2fa782020-05-10 11:05:29 +020011341 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011342}
Larry Hastings2f936352014-08-05 14:04:04 +100011343#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
11344
Guido van Rossum94f6f721999-01-06 18:42:14 +000011345
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011346#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011347/*[clinic input]
11348os._getdiskusage
11349
Steve Dower23ad6d02018-02-22 10:39:10 -080011350 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100011351
11352Return disk usage statistics about the given path as a (total, free) tuple.
11353[clinic start generated code]*/
11354
Larry Hastings2f936352014-08-05 14:04:04 +100011355static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080011356os__getdiskusage_impl(PyObject *module, path_t *path)
11357/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011358{
11359 BOOL retval;
11360 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040011361 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011362
11363 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080011364 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011365 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040011366 if (retval == 0) {
11367 if (GetLastError() == ERROR_DIRECTORY) {
11368 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011369
Joe Pamerc8c02492018-09-25 10:57:36 -040011370 dir_path = PyMem_New(wchar_t, path->length + 1);
11371 if (dir_path == NULL) {
11372 return PyErr_NoMemory();
11373 }
11374
11375 wcscpy_s(dir_path, path->length + 1, path->wide);
11376
11377 if (_dirnameW(dir_path) != -1) {
11378 Py_BEGIN_ALLOW_THREADS
11379 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
11380 Py_END_ALLOW_THREADS
11381 }
11382 /* Record the last error in case it's modified by PyMem_Free. */
11383 err = GetLastError();
11384 PyMem_Free(dir_path);
11385 if (retval) {
11386 goto success;
11387 }
11388 }
11389 return PyErr_SetFromWindowsErr(err);
11390 }
11391
11392success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011393 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
11394}
Larry Hastings2f936352014-08-05 14:04:04 +100011395#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011396
11397
Fred Drakec9680921999-12-13 16:37:25 +000011398/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
11399 * It maps strings representing configuration variable names to
11400 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000011401 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000011402 * rarely-used constants. There are three separate tables that use
11403 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000011404 *
11405 * This code is always included, even if none of the interfaces that
11406 * need it are included. The #if hackery needed to avoid it would be
11407 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000011408 */
11409struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011410 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011411 int value;
Fred Drakec9680921999-12-13 16:37:25 +000011412};
11413
Fred Drake12c6e2d1999-12-14 21:25:03 +000011414static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011415conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000011416 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000011417{
Christian Heimes217cfd12007-12-02 14:31:20 +000011418 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011419 int value = _PyLong_AsInt(arg);
11420 if (value == -1 && PyErr_Occurred())
11421 return 0;
11422 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000011423 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000011424 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000011425 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000011426 /* look up the value in the table using a binary search */
11427 size_t lo = 0;
11428 size_t mid;
11429 size_t hi = tablesize;
11430 int cmp;
11431 const char *confname;
11432 if (!PyUnicode_Check(arg)) {
11433 PyErr_SetString(PyExc_TypeError,
11434 "configuration names must be strings or integers");
11435 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011436 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020011437 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000011438 if (confname == NULL)
11439 return 0;
11440 while (lo < hi) {
11441 mid = (lo + hi) / 2;
11442 cmp = strcmp(confname, table[mid].name);
11443 if (cmp < 0)
11444 hi = mid;
11445 else if (cmp > 0)
11446 lo = mid + 1;
11447 else {
11448 *valuep = table[mid].value;
11449 return 1;
11450 }
11451 }
11452 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
11453 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000011455}
11456
11457
11458#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
11459static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011460#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011461 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011462#endif
11463#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011464 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011465#endif
Fred Drakec9680921999-12-13 16:37:25 +000011466#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011467 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011468#endif
11469#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000011470 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000011471#endif
11472#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000011473 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000011474#endif
11475#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000011476 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000011477#endif
11478#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011479 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011480#endif
11481#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000011482 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000011483#endif
11484#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011485 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000011486#endif
11487#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011488 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011489#endif
11490#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011491 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000011492#endif
11493#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011494 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011495#endif
11496#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011497 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000011498#endif
11499#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011500 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011501#endif
11502#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011503 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000011504#endif
11505#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011506 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011507#endif
11508#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011509 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000011510#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000011511#ifdef _PC_ACL_ENABLED
11512 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
11513#endif
11514#ifdef _PC_MIN_HOLE_SIZE
11515 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
11516#endif
11517#ifdef _PC_ALLOC_SIZE_MIN
11518 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
11519#endif
11520#ifdef _PC_REC_INCR_XFER_SIZE
11521 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
11522#endif
11523#ifdef _PC_REC_MAX_XFER_SIZE
11524 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
11525#endif
11526#ifdef _PC_REC_MIN_XFER_SIZE
11527 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
11528#endif
11529#ifdef _PC_REC_XFER_ALIGN
11530 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
11531#endif
11532#ifdef _PC_SYMLINK_MAX
11533 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
11534#endif
11535#ifdef _PC_XATTR_ENABLED
11536 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
11537#endif
11538#ifdef _PC_XATTR_EXISTS
11539 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
11540#endif
11541#ifdef _PC_TIMESTAMP_RESOLUTION
11542 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
11543#endif
Fred Drakec9680921999-12-13 16:37:25 +000011544};
11545
Fred Drakec9680921999-12-13 16:37:25 +000011546static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011547conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011548{
11549 return conv_confname(arg, valuep, posix_constants_pathconf,
11550 sizeof(posix_constants_pathconf)
11551 / sizeof(struct constdef));
11552}
11553#endif
11554
Larry Hastings2f936352014-08-05 14:04:04 +100011555
Fred Drakec9680921999-12-13 16:37:25 +000011556#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011557/*[clinic input]
11558os.fpathconf -> long
11559
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011560 fd: fildes
Larry Hastings2f936352014-08-05 14:04:04 +100011561 name: path_confname
11562 /
11563
11564Return the configuration limit name for the file descriptor fd.
11565
11566If there is no limit, return -1.
11567[clinic start generated code]*/
11568
Larry Hastings2f936352014-08-05 14:04:04 +100011569static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011570os_fpathconf_impl(PyObject *module, int fd, int name)
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011571/*[clinic end generated code: output=d5b7042425fc3e21 input=5b8d2471cfaae186]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011572{
11573 long limit;
11574
11575 errno = 0;
11576 limit = fpathconf(fd, name);
11577 if (limit == -1 && errno != 0)
11578 posix_error();
11579
11580 return limit;
11581}
11582#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011583
11584
11585#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011586/*[clinic input]
11587os.pathconf -> long
11588 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
11589 name: path_confname
11590
11591Return the configuration limit name for the file or directory path.
11592
11593If there is no limit, return -1.
11594On some platforms, path may also be specified as an open file descriptor.
11595 If this functionality is unavailable, using it raises an exception.
11596[clinic start generated code]*/
11597
Larry Hastings2f936352014-08-05 14:04:04 +100011598static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011599os_pathconf_impl(PyObject *module, path_t *path, int name)
11600/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011601{
Victor Stinner8c62be82010-05-06 00:08:46 +000011602 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000011603
Victor Stinner8c62be82010-05-06 00:08:46 +000011604 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020011605#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011606 if (path->fd != -1)
11607 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011608 else
11609#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011610 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011611 if (limit == -1 && errno != 0) {
11612 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011613 /* could be a path or name problem */
11614 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011615 else
Larry Hastings2f936352014-08-05 14:04:04 +100011616 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011617 }
Larry Hastings2f936352014-08-05 14:04:04 +100011618
11619 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011620}
Larry Hastings2f936352014-08-05 14:04:04 +100011621#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011622
11623#ifdef HAVE_CONFSTR
11624static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011625#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011626 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011627#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011628#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011629 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011630#endif
11631#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011632 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011633#endif
Fred Draked86ed291999-12-15 15:34:33 +000011634#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011635 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011636#endif
11637#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011638 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011639#endif
11640#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011641 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011642#endif
11643#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011644 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011645#endif
Fred Drakec9680921999-12-13 16:37:25 +000011646#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011647 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011648#endif
11649#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011650 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011651#endif
11652#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011653 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011654#endif
11655#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011656 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011657#endif
11658#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011659 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011660#endif
11661#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011662 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011663#endif
11664#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011665 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011666#endif
11667#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011668 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011669#endif
Fred Draked86ed291999-12-15 15:34:33 +000011670#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011671 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011672#endif
Fred Drakec9680921999-12-13 16:37:25 +000011673#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011674 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011675#endif
Fred Draked86ed291999-12-15 15:34:33 +000011676#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011677 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011678#endif
11679#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011680 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011681#endif
11682#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011683 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011684#endif
11685#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011686 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011687#endif
Fred Drakec9680921999-12-13 16:37:25 +000011688#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011689 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011690#endif
11691#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011692 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011693#endif
11694#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011695 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011696#endif
11697#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011698 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011699#endif
11700#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011701 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011702#endif
11703#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011704 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011705#endif
11706#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011707 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011708#endif
11709#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011710 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011711#endif
11712#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011713 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011714#endif
11715#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011716 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011717#endif
11718#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011719 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011720#endif
11721#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011722 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011723#endif
11724#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011725 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011726#endif
11727#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011728 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011729#endif
11730#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011731 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011732#endif
11733#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011734 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011735#endif
Fred Draked86ed291999-12-15 15:34:33 +000011736#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011737 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011738#endif
11739#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011740 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011741#endif
11742#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011743 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011744#endif
11745#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011746 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011747#endif
11748#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011749 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011750#endif
11751#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011752 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011753#endif
11754#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011755 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011756#endif
11757#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011758 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011759#endif
11760#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011761 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011762#endif
11763#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011764 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011765#endif
11766#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011767 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011768#endif
11769#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011770 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011771#endif
11772#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011773 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011774#endif
Fred Drakec9680921999-12-13 16:37:25 +000011775};
11776
11777static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011778conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011779{
11780 return conv_confname(arg, valuep, posix_constants_confstr,
11781 sizeof(posix_constants_confstr)
11782 / sizeof(struct constdef));
11783}
11784
Larry Hastings2f936352014-08-05 14:04:04 +100011785
11786/*[clinic input]
11787os.confstr
11788
11789 name: confstr_confname
11790 /
11791
11792Return a string-valued system configuration variable.
11793[clinic start generated code]*/
11794
Larry Hastings2f936352014-08-05 14:04:04 +100011795static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011796os_confstr_impl(PyObject *module, int name)
11797/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011798{
11799 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011800 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011801 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011802
Victor Stinnercb043522010-09-10 23:49:04 +000011803 errno = 0;
11804 len = confstr(name, buffer, sizeof(buffer));
11805 if (len == 0) {
11806 if (errno) {
11807 posix_error();
11808 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011809 }
11810 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011811 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011812 }
11813 }
Victor Stinnercb043522010-09-10 23:49:04 +000011814
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011815 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011816 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011817 char *buf = PyMem_Malloc(len);
11818 if (buf == NULL)
11819 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011820 len2 = confstr(name, buf, len);
11821 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011822 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011823 PyMem_Free(buf);
11824 }
11825 else
11826 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011827 return result;
11828}
Larry Hastings2f936352014-08-05 14:04:04 +100011829#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011830
11831
11832#ifdef HAVE_SYSCONF
11833static struct constdef posix_constants_sysconf[] = {
11834#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011835 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011836#endif
11837#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011838 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011839#endif
11840#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011841 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011842#endif
11843#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011844 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011845#endif
11846#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011847 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011848#endif
11849#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011850 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011851#endif
11852#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011853 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011854#endif
11855#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011856 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011857#endif
11858#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011859 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011860#endif
11861#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011862 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011863#endif
Fred Draked86ed291999-12-15 15:34:33 +000011864#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011865 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011866#endif
11867#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011868 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011869#endif
Fred Drakec9680921999-12-13 16:37:25 +000011870#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011871 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011872#endif
Fred Drakec9680921999-12-13 16:37:25 +000011873#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011874 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011875#endif
11876#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011877 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011878#endif
11879#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011880 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011881#endif
11882#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011883 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011884#endif
11885#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011886 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011887#endif
Fred Draked86ed291999-12-15 15:34:33 +000011888#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011889 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011890#endif
Fred Drakec9680921999-12-13 16:37:25 +000011891#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011892 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011893#endif
11894#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011895 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011896#endif
11897#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011898 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011899#endif
11900#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011901 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011902#endif
11903#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011904 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011905#endif
Fred Draked86ed291999-12-15 15:34:33 +000011906#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011907 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011908#endif
Fred Drakec9680921999-12-13 16:37:25 +000011909#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011910 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011911#endif
11912#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011913 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011914#endif
11915#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011916 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011917#endif
11918#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011919 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011920#endif
11921#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011922 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011923#endif
11924#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011925 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011926#endif
11927#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011928 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011929#endif
11930#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011931 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011932#endif
11933#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011934 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011935#endif
11936#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011937 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011938#endif
11939#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011940 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011941#endif
11942#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011943 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011944#endif
11945#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011946 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011947#endif
11948#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011949 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011950#endif
11951#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011952 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011953#endif
11954#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011955 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011956#endif
11957#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011958 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011959#endif
11960#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011961 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011962#endif
11963#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011964 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011965#endif
11966#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011967 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011968#endif
11969#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011970 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011971#endif
11972#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011973 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011974#endif
11975#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011976 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011977#endif
Fred Draked86ed291999-12-15 15:34:33 +000011978#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011979 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011980#endif
Fred Drakec9680921999-12-13 16:37:25 +000011981#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011982 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011983#endif
11984#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011985 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011986#endif
11987#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011988 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011989#endif
Fred Draked86ed291999-12-15 15:34:33 +000011990#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011991 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011992#endif
Fred Drakec9680921999-12-13 16:37:25 +000011993#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011994 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011995#endif
Fred Draked86ed291999-12-15 15:34:33 +000011996#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011997 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011998#endif
11999#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000012000 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000012001#endif
Fred Drakec9680921999-12-13 16:37:25 +000012002#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012003 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012004#endif
12005#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012006 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012007#endif
12008#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012009 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012010#endif
12011#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012012 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000012013#endif
Fred Draked86ed291999-12-15 15:34:33 +000012014#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000012015 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000012016#endif
Fred Drakec9680921999-12-13 16:37:25 +000012017#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000012018 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000012019#endif
12020#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000012021 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000012022#endif
12023#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012024 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012025#endif
12026#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000012027 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000012028#endif
12029#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000012030 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000012031#endif
12032#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000012033 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000012034#endif
12035#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000012036 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000012037#endif
Fred Draked86ed291999-12-15 15:34:33 +000012038#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000012039 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000012040#endif
Fred Drakec9680921999-12-13 16:37:25 +000012041#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012042 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012043#endif
12044#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012045 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012046#endif
Fred Draked86ed291999-12-15 15:34:33 +000012047#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012048 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000012049#endif
Fred Drakec9680921999-12-13 16:37:25 +000012050#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012051 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012052#endif
12053#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012054 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012055#endif
12056#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012057 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012058#endif
12059#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012060 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012061#endif
12062#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012063 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012064#endif
12065#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012066 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012067#endif
12068#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012069 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012070#endif
12071#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000012072 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000012073#endif
12074#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000012075 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000012076#endif
Fred Draked86ed291999-12-15 15:34:33 +000012077#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000012078 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000012079#endif
12080#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000012081 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000012082#endif
Fred Drakec9680921999-12-13 16:37:25 +000012083#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000012084 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000012085#endif
12086#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012087 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012088#endif
12089#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012090 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012091#endif
12092#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012093 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012094#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030012095#ifdef _SC_AIX_REALMEM
12096 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
12097#endif
Fred Drakec9680921999-12-13 16:37:25 +000012098#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012099 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012100#endif
12101#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000012102 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000012103#endif
12104#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000012105 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000012106#endif
12107#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000012108 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000012109#endif
12110#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012111 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000012112#endif
12113#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012114 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000012115#endif
12116#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000012117 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000012118#endif
12119#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012120 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000012121#endif
12122#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012123 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000012124#endif
12125#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000012126 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000012127#endif
12128#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000012129 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000012130#endif
12131#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000012132 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000012133#endif
12134#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000012135 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000012136#endif
12137#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012138 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012139#endif
12140#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012141 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012142#endif
12143#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000012144 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000012145#endif
12146#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012147 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012148#endif
12149#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012150 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012151#endif
12152#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000012153 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000012154#endif
12155#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012156 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012157#endif
12158#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012159 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012160#endif
12161#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012162 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000012163#endif
12164#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000012165 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000012166#endif
12167#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012168 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012169#endif
12170#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012171 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012172#endif
12173#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012174 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000012175#endif
12176#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012177 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012178#endif
12179#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012180 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012181#endif
12182#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012183 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012184#endif
12185#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012186 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012187#endif
12188#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012189 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012190#endif
Fred Draked86ed291999-12-15 15:34:33 +000012191#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000012192 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000012193#endif
Fred Drakec9680921999-12-13 16:37:25 +000012194#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000012195 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000012196#endif
12197#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012198 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012199#endif
12200#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000012201 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000012202#endif
12203#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012204 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012205#endif
12206#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012207 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012208#endif
12209#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012210 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012211#endif
12212#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000012213 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000012214#endif
12215#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012216 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012217#endif
12218#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012219 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012220#endif
12221#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012222 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012223#endif
12224#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012225 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012226#endif
12227#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012228 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000012229#endif
12230#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012231 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000012232#endif
12233#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000012234 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000012235#endif
12236#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012237 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012238#endif
12239#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012240 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012241#endif
12242#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012243 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012244#endif
12245#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000012246 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000012247#endif
12248#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012249 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012250#endif
12251#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012252 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012253#endif
12254#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012255 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012256#endif
12257#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012258 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012259#endif
12260#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012261 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012262#endif
12263#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012264 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012265#endif
12266#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000012267 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000012268#endif
12269#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012270 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012271#endif
12272#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012273 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012274#endif
12275#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012276 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012277#endif
12278#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012279 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000012280#endif
12281#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000012282 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000012283#endif
12284#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012285 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012286#endif
12287#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000012288 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000012289#endif
12290#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012291 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012292#endif
12293#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000012294 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000012295#endif
12296#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000012297 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000012298#endif
12299#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000012300 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000012301#endif
12302#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012303 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000012304#endif
12305#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012306 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012307#endif
12308#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000012309 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000012310#endif
12311#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000012312 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000012313#endif
12314#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012315 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012316#endif
12317#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012318 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012319#endif
12320#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000012321 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000012322#endif
12323#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000012324 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000012325#endif
12326#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000012327 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000012328#endif
12329};
12330
12331static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012332conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000012333{
12334 return conv_confname(arg, valuep, posix_constants_sysconf,
12335 sizeof(posix_constants_sysconf)
12336 / sizeof(struct constdef));
12337}
12338
Larry Hastings2f936352014-08-05 14:04:04 +100012339
12340/*[clinic input]
12341os.sysconf -> long
12342 name: sysconf_confname
12343 /
12344
12345Return an integer-valued system configuration variable.
12346[clinic start generated code]*/
12347
Larry Hastings2f936352014-08-05 14:04:04 +100012348static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012349os_sysconf_impl(PyObject *module, int name)
12350/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012351{
12352 long value;
12353
12354 errno = 0;
12355 value = sysconf(name);
12356 if (value == -1 && errno != 0)
12357 posix_error();
12358 return value;
12359}
12360#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000012361
12362
Fred Drakebec628d1999-12-15 18:31:10 +000012363/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020012364 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000012365 * the exported dictionaries that are used to publish information about the
12366 * names available on the host platform.
12367 *
12368 * Sorting the table at runtime ensures that the table is properly ordered
12369 * when used, even for platforms we're not able to test on. It also makes
12370 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000012371 */
Fred Drakebec628d1999-12-15 18:31:10 +000012372
12373static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012374cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000012375{
12376 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012377 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000012378 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012379 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000012380
12381 return strcmp(c1->name, c2->name);
12382}
12383
12384static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012385setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012386 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012387{
Fred Drakebec628d1999-12-15 18:31:10 +000012388 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000012389 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000012390
12391 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
12392 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000012393 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000012394 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012395
Barry Warsaw3155db32000-04-13 15:20:40 +000012396 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000012397 PyObject *o = PyLong_FromLong(table[i].value);
12398 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
12399 Py_XDECREF(o);
12400 Py_DECREF(d);
12401 return -1;
12402 }
12403 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000012404 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000012405 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000012406}
12407
Fred Drakebec628d1999-12-15 18:31:10 +000012408/* Return -1 on failure, 0 on success. */
12409static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000012410setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012411{
12412#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000012413 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000012414 sizeof(posix_constants_pathconf)
12415 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012416 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012417 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012418#endif
12419#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000012420 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000012421 sizeof(posix_constants_confstr)
12422 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012423 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012424 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012425#endif
12426#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000012427 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000012428 sizeof(posix_constants_sysconf)
12429 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012430 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012431 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012432#endif
Fred Drakebec628d1999-12-15 18:31:10 +000012433 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000012434}
Fred Draked86ed291999-12-15 15:34:33 +000012435
12436
Larry Hastings2f936352014-08-05 14:04:04 +100012437/*[clinic input]
12438os.abort
12439
12440Abort the interpreter immediately.
12441
12442This function 'dumps core' or otherwise fails in the hardest way possible
12443on the hosting operating system. This function never returns.
12444[clinic start generated code]*/
12445
Larry Hastings2f936352014-08-05 14:04:04 +100012446static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012447os_abort_impl(PyObject *module)
12448/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012449{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012450 abort();
12451 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010012452#ifndef __clang__
12453 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
12454 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
12455 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012456 Py_FatalError("abort() called from Python code didn't abort!");
12457 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010012458#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012459}
Fred Drakebec628d1999-12-15 18:31:10 +000012460
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000012461#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012462/* Grab ShellExecute dynamically from shell32 */
12463static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012464static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
12465 LPCWSTR, INT);
12466static int
12467check_ShellExecute()
12468{
12469 HINSTANCE hShell32;
12470
12471 /* only recheck */
12472 if (-1 == has_ShellExecute) {
12473 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070012474 /* Security note: this call is not vulnerable to "DLL hijacking".
12475 SHELL32 is part of "KnownDLLs" and so Windows always load
12476 the system SHELL32.DLL, even if there is another SHELL32.DLL
12477 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080012478 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080012479 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080012480 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
12481 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070012482 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012483 } else {
12484 has_ShellExecute = 0;
12485 }
Tony Roberts4860f012019-02-02 18:16:42 +010012486 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012487 }
12488 return has_ShellExecute;
12489}
12490
12491
Steve Dowercc16be82016-09-08 10:35:16 -070012492/*[clinic input]
12493os.startfile
12494 filepath: path_t
12495 operation: Py_UNICODE = NULL
Steve Dower019e9e82021-04-23 18:03:17 +010012496 arguments: Py_UNICODE = NULL
12497 cwd: path_t(nullable=True) = None
12498 show_cmd: int = 1
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000012499
Steve Dowercc16be82016-09-08 10:35:16 -070012500Start a file with its associated application.
12501
12502When "operation" is not specified or "open", this acts like
12503double-clicking the file in Explorer, or giving the file name as an
12504argument to the DOS "start" command: the file is opened with whatever
12505application (if any) its extension is associated.
12506When another "operation" is given, it specifies what should be done with
12507the file. A typical operation is "print".
12508
Steve Dower019e9e82021-04-23 18:03:17 +010012509"arguments" is passed to the application, but should be omitted if the
12510file is a document.
12511
12512"cwd" is the working directory for the operation. If "filepath" is
12513relative, it will be resolved against this directory. This argument
12514should usually be an absolute path.
12515
12516"show_cmd" can be used to override the recommended visibility option.
12517See the Windows ShellExecute documentation for values.
12518
Steve Dowercc16be82016-09-08 10:35:16 -070012519startfile returns as soon as the associated application is launched.
12520There is no option to wait for the application to close, and no way
12521to retrieve the application's exit status.
12522
12523The filepath is relative to the current directory. If you want to use
12524an absolute path, make sure the first character is not a slash ("/");
12525the underlying Win32 ShellExecute function doesn't work if it is.
12526[clinic start generated code]*/
12527
12528static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020012529os_startfile_impl(PyObject *module, path_t *filepath,
Steve Dower019e9e82021-04-23 18:03:17 +010012530 const Py_UNICODE *operation, const Py_UNICODE *arguments,
12531 path_t *cwd, int show_cmd)
12532/*[clinic end generated code: output=3baa4f9795841880 input=8248997b80669622]*/
Steve Dowercc16be82016-09-08 10:35:16 -070012533{
12534 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012535
12536 if(!check_ShellExecute()) {
12537 /* If the OS doesn't have ShellExecute, return a
12538 NotImplementedError. */
12539 return PyErr_Format(PyExc_NotImplementedError,
12540 "startfile not available on this platform");
12541 }
12542
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012543 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080012544 return NULL;
12545 }
Steve Dower019e9e82021-04-23 18:03:17 +010012546 if (PySys_Audit("os.startfile/2", "OuuOi", filepath->object, operation,
12547 arguments, cwd->object ? cwd->object : Py_None,
12548 show_cmd) < 0) {
12549 return NULL;
12550 }
Saiyang Gou95f60012020-02-04 16:15:00 -080012551
Victor Stinner8c62be82010-05-06 00:08:46 +000012552 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070012553 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower019e9e82021-04-23 18:03:17 +010012554 arguments, cwd->wide, show_cmd);
Victor Stinner8c62be82010-05-06 00:08:46 +000012555 Py_END_ALLOW_THREADS
12556
Victor Stinner8c62be82010-05-06 00:08:46 +000012557 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070012558 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020012559 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012560 }
Steve Dowercc16be82016-09-08 10:35:16 -070012561 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000012562}
Larry Hastings2f936352014-08-05 14:04:04 +100012563#endif /* MS_WINDOWS */
12564
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012565
Martin v. Löwis438b5342002-12-27 10:16:42 +000012566#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100012567/*[clinic input]
12568os.getloadavg
12569
12570Return average recent system load information.
12571
12572Return the number of processes in the system run queue averaged over
12573the last 1, 5, and 15 minutes as a tuple of three floats.
12574Raises OSError if the load average was unobtainable.
12575[clinic start generated code]*/
12576
Larry Hastings2f936352014-08-05 14:04:04 +100012577static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012578os_getloadavg_impl(PyObject *module)
12579/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000012580{
12581 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000012582 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000012583 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
12584 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000012585 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000012586 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000012587}
Larry Hastings2f936352014-08-05 14:04:04 +100012588#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000012589
Larry Hastings2f936352014-08-05 14:04:04 +100012590
12591/*[clinic input]
12592os.device_encoding
12593 fd: int
12594
12595Return a string describing the encoding of a terminal's file descriptor.
12596
12597The file descriptor must be attached to a terminal.
12598If the device is not a terminal, return None.
12599[clinic start generated code]*/
12600
Larry Hastings2f936352014-08-05 14:04:04 +100012601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012602os_device_encoding_impl(PyObject *module, int fd)
12603/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012604{
Brett Cannonefb00c02012-02-29 18:31:31 -050012605 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000012606}
12607
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012608
Larry Hastings2f936352014-08-05 14:04:04 +100012609#ifdef HAVE_SETRESUID
12610/*[clinic input]
12611os.setresuid
12612
12613 ruid: uid_t
12614 euid: uid_t
12615 suid: uid_t
12616 /
12617
12618Set the current process's real, effective, and saved user ids.
12619[clinic start generated code]*/
12620
Larry Hastings2f936352014-08-05 14:04:04 +100012621static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012622os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12623/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012624{
Victor Stinner8c62be82010-05-06 00:08:46 +000012625 if (setresuid(ruid, euid, suid) < 0)
12626 return posix_error();
12627 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012628}
Larry Hastings2f936352014-08-05 14:04:04 +100012629#endif /* HAVE_SETRESUID */
12630
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012631
12632#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012633/*[clinic input]
12634os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012635
Larry Hastings2f936352014-08-05 14:04:04 +100012636 rgid: gid_t
12637 egid: gid_t
12638 sgid: gid_t
12639 /
12640
12641Set the current process's real, effective, and saved group ids.
12642[clinic start generated code]*/
12643
Larry Hastings2f936352014-08-05 14:04:04 +100012644static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012645os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12646/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012647{
Victor Stinner8c62be82010-05-06 00:08:46 +000012648 if (setresgid(rgid, egid, sgid) < 0)
12649 return posix_error();
12650 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012651}
Larry Hastings2f936352014-08-05 14:04:04 +100012652#endif /* HAVE_SETRESGID */
12653
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012654
12655#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012656/*[clinic input]
12657os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012658
Larry Hastings2f936352014-08-05 14:04:04 +100012659Return a tuple of the current process's real, effective, and saved user ids.
12660[clinic start generated code]*/
12661
Larry Hastings2f936352014-08-05 14:04:04 +100012662static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012663os_getresuid_impl(PyObject *module)
12664/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012665{
Victor Stinner8c62be82010-05-06 00:08:46 +000012666 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012667 if (getresuid(&ruid, &euid, &suid) < 0)
12668 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012669 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12670 _PyLong_FromUid(euid),
12671 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012672}
Larry Hastings2f936352014-08-05 14:04:04 +100012673#endif /* HAVE_GETRESUID */
12674
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012675
12676#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012677/*[clinic input]
12678os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012679
Larry Hastings2f936352014-08-05 14:04:04 +100012680Return a tuple of the current process's real, effective, and saved group ids.
12681[clinic start generated code]*/
12682
Larry Hastings2f936352014-08-05 14:04:04 +100012683static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012684os_getresgid_impl(PyObject *module)
12685/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012686{
12687 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012688 if (getresgid(&rgid, &egid, &sgid) < 0)
12689 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012690 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12691 _PyLong_FromGid(egid),
12692 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012693}
Larry Hastings2f936352014-08-05 14:04:04 +100012694#endif /* HAVE_GETRESGID */
12695
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012696
Benjamin Peterson9428d532011-09-14 11:45:52 -040012697#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012698/*[clinic input]
12699os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012700
Larry Hastings2f936352014-08-05 14:04:04 +100012701 path: path_t(allow_fd=True)
12702 attribute: path_t
12703 *
12704 follow_symlinks: bool = True
12705
12706Return the value of extended attribute attribute on path.
12707
BNMetricsb9427072018-11-02 15:20:19 +000012708path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012709If follow_symlinks is False, and the last element of the path is a symbolic
12710 link, getxattr will examine the symbolic link itself instead of the file
12711 the link points to.
12712
12713[clinic start generated code]*/
12714
Larry Hastings2f936352014-08-05 14:04:04 +100012715static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012716os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012717 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012718/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012719{
12720 Py_ssize_t i;
12721 PyObject *buffer = NULL;
12722
12723 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12724 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012725
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012726 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12727 return NULL;
12728 }
12729
Larry Hastings9cf065c2012-06-22 16:30:09 -070012730 for (i = 0; ; i++) {
12731 void *ptr;
12732 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012733 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012734 Py_ssize_t buffer_size = buffer_sizes[i];
12735 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012736 path_error(path);
12737 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012738 }
12739 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12740 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012741 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012742 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012743
Larry Hastings9cf065c2012-06-22 16:30:09 -070012744 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012745 if (path->fd >= 0)
12746 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012747 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012748 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012749 else
Larry Hastings2f936352014-08-05 14:04:04 +100012750 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012751 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012752
Larry Hastings9cf065c2012-06-22 16:30:09 -070012753 if (result < 0) {
12754 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012755 if (errno == ERANGE)
12756 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012757 path_error(path);
12758 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012759 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012760
Larry Hastings9cf065c2012-06-22 16:30:09 -070012761 if (result != buffer_size) {
12762 /* Can only shrink. */
12763 _PyBytes_Resize(&buffer, result);
12764 }
12765 break;
12766 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012767
Larry Hastings9cf065c2012-06-22 16:30:09 -070012768 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012769}
12770
Larry Hastings2f936352014-08-05 14:04:04 +100012771
12772/*[clinic input]
12773os.setxattr
12774
12775 path: path_t(allow_fd=True)
12776 attribute: path_t
12777 value: Py_buffer
12778 flags: int = 0
12779 *
12780 follow_symlinks: bool = True
12781
12782Set extended attribute attribute on path to value.
12783
BNMetricsb9427072018-11-02 15:20:19 +000012784path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012785If follow_symlinks is False, and the last element of the path is a symbolic
12786 link, setxattr will modify the symbolic link itself instead of the file
12787 the link points to.
12788
12789[clinic start generated code]*/
12790
Benjamin Peterson799bd802011-08-31 22:15:17 -040012791static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012792os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012793 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012794/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012795{
Larry Hastings2f936352014-08-05 14:04:04 +100012796 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012797
Larry Hastings2f936352014-08-05 14:04:04 +100012798 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012799 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012800
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012801 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12802 value->buf, value->len, flags) < 0) {
12803 return NULL;
12804 }
12805
Benjamin Peterson799bd802011-08-31 22:15:17 -040012806 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012807 if (path->fd > -1)
12808 result = fsetxattr(path->fd, attribute->narrow,
12809 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012810 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012811 result = setxattr(path->narrow, attribute->narrow,
12812 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012813 else
Larry Hastings2f936352014-08-05 14:04:04 +100012814 result = lsetxattr(path->narrow, attribute->narrow,
12815 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012816 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012817
Larry Hastings9cf065c2012-06-22 16:30:09 -070012818 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012819 path_error(path);
12820 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012821 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012822
Larry Hastings2f936352014-08-05 14:04:04 +100012823 Py_RETURN_NONE;
12824}
12825
12826
12827/*[clinic input]
12828os.removexattr
12829
12830 path: path_t(allow_fd=True)
12831 attribute: path_t
12832 *
12833 follow_symlinks: bool = True
12834
12835Remove extended attribute attribute on path.
12836
BNMetricsb9427072018-11-02 15:20:19 +000012837path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012838If follow_symlinks is False, and the last element of the path is a symbolic
12839 link, removexattr will modify the symbolic link itself instead of the file
12840 the link points to.
12841
12842[clinic start generated code]*/
12843
Larry Hastings2f936352014-08-05 14:04:04 +100012844static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012845os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012846 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012847/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012848{
12849 ssize_t result;
12850
12851 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12852 return NULL;
12853
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012854 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12855 return NULL;
12856 }
12857
Larry Hastings2f936352014-08-05 14:04:04 +100012858 Py_BEGIN_ALLOW_THREADS;
12859 if (path->fd > -1)
12860 result = fremovexattr(path->fd, attribute->narrow);
12861 else if (follow_symlinks)
12862 result = removexattr(path->narrow, attribute->narrow);
12863 else
12864 result = lremovexattr(path->narrow, attribute->narrow);
12865 Py_END_ALLOW_THREADS;
12866
12867 if (result) {
12868 return path_error(path);
12869 }
12870
12871 Py_RETURN_NONE;
12872}
12873
12874
12875/*[clinic input]
12876os.listxattr
12877
12878 path: path_t(allow_fd=True, nullable=True) = None
12879 *
12880 follow_symlinks: bool = True
12881
12882Return a list of extended attributes on path.
12883
BNMetricsb9427072018-11-02 15:20:19 +000012884path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012885if path is None, listxattr will examine the current directory.
12886If follow_symlinks is False, and the last element of the path is a symbolic
12887 link, listxattr will examine the symbolic link itself instead of the file
12888 the link points to.
12889[clinic start generated code]*/
12890
Larry Hastings2f936352014-08-05 14:04:04 +100012891static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012892os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012893/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012894{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012895 Py_ssize_t i;
12896 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012897 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012898 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012899
Larry Hastings2f936352014-08-05 14:04:04 +100012900 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012901 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012902
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012903 if (PySys_Audit("os.listxattr", "(O)",
12904 path->object ? path->object : Py_None) < 0) {
12905 return NULL;
12906 }
12907
Larry Hastings2f936352014-08-05 14:04:04 +100012908 name = path->narrow ? path->narrow : ".";
12909
Larry Hastings9cf065c2012-06-22 16:30:09 -070012910 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012911 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012912 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012913 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012914 Py_ssize_t buffer_size = buffer_sizes[i];
12915 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012916 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012917 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012918 break;
12919 }
Victor Stinner00d7abd2020-12-01 09:56:42 +010012920 buffer = PyMem_Malloc(buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012921 if (!buffer) {
12922 PyErr_NoMemory();
12923 break;
12924 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012925
Larry Hastings9cf065c2012-06-22 16:30:09 -070012926 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012927 if (path->fd > -1)
12928 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012929 else if (follow_symlinks)
12930 length = listxattr(name, buffer, buffer_size);
12931 else
12932 length = llistxattr(name, buffer, buffer_size);
12933 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012934
Larry Hastings9cf065c2012-06-22 16:30:09 -070012935 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012936 if (errno == ERANGE) {
Victor Stinner00d7abd2020-12-01 09:56:42 +010012937 PyMem_Free(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012938 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012939 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012940 }
Larry Hastings2f936352014-08-05 14:04:04 +100012941 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012942 break;
12943 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012944
Larry Hastings9cf065c2012-06-22 16:30:09 -070012945 result = PyList_New(0);
12946 if (!result) {
12947 goto exit;
12948 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012949
Larry Hastings9cf065c2012-06-22 16:30:09 -070012950 end = buffer + length;
12951 for (trace = start = buffer; trace != end; trace++) {
12952 if (!*trace) {
12953 int error;
12954 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12955 trace - start);
12956 if (!attribute) {
12957 Py_DECREF(result);
12958 result = NULL;
12959 goto exit;
12960 }
12961 error = PyList_Append(result, attribute);
12962 Py_DECREF(attribute);
12963 if (error) {
12964 Py_DECREF(result);
12965 result = NULL;
12966 goto exit;
12967 }
12968 start = trace + 1;
12969 }
12970 }
12971 break;
12972 }
12973exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012974 if (buffer)
Victor Stinner00d7abd2020-12-01 09:56:42 +010012975 PyMem_Free(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012976 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012977}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012978#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012979
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012980
Larry Hastings2f936352014-08-05 14:04:04 +100012981/*[clinic input]
12982os.urandom
12983
12984 size: Py_ssize_t
12985 /
12986
12987Return a bytes object containing random bytes suitable for cryptographic use.
12988[clinic start generated code]*/
12989
Larry Hastings2f936352014-08-05 14:04:04 +100012990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012991os_urandom_impl(PyObject *module, Py_ssize_t size)
12992/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012993{
12994 PyObject *bytes;
12995 int result;
12996
Georg Brandl2fb477c2012-02-21 00:33:36 +010012997 if (size < 0)
12998 return PyErr_Format(PyExc_ValueError,
12999 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100013000 bytes = PyBytes_FromStringAndSize(NULL, size);
13001 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010013002 return NULL;
13003
Victor Stinnere66987e2016-09-06 16:33:52 -070013004 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100013005 if (result == -1) {
13006 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010013007 return NULL;
13008 }
Larry Hastings2f936352014-08-05 14:04:04 +100013009 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010013010}
13011
Zackery Spytz43fdbd22019-05-29 13:57:07 -060013012#ifdef HAVE_MEMFD_CREATE
13013/*[clinic input]
13014os.memfd_create
13015
13016 name: FSConverter
13017 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
13018
13019[clinic start generated code]*/
13020
13021static PyObject *
13022os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
13023/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
13024{
13025 int fd;
13026 const char *bytes = PyBytes_AS_STRING(name);
13027 Py_BEGIN_ALLOW_THREADS
13028 fd = memfd_create(bytes, flags);
13029 Py_END_ALLOW_THREADS
13030 if (fd == -1) {
13031 return PyErr_SetFromErrno(PyExc_OSError);
13032 }
13033 return PyLong_FromLong(fd);
13034}
13035#endif
13036
Christian Heimescd9fed62020-11-13 19:48:52 +010013037#ifdef HAVE_EVENTFD
13038/*[clinic input]
13039os.eventfd
13040
13041 initval: unsigned_int
13042 flags: int(c_default="EFD_CLOEXEC") = EFD_CLOEXEC
13043
13044Creates and returns an event notification file descriptor.
13045[clinic start generated code]*/
13046
13047static PyObject *
13048os_eventfd_impl(PyObject *module, unsigned int initval, int flags)
13049/*[clinic end generated code: output=ce9c9bbd1446f2de input=66203e3c50c4028b]*/
13050
13051{
13052 /* initval is limited to uint32_t, internal counter is uint64_t */
13053 int fd;
13054 Py_BEGIN_ALLOW_THREADS
13055 fd = eventfd(initval, flags);
13056 Py_END_ALLOW_THREADS
13057 if (fd == -1) {
13058 return PyErr_SetFromErrno(PyExc_OSError);
13059 }
13060 return PyLong_FromLong(fd);
13061}
13062
13063/*[clinic input]
13064os.eventfd_read
13065
13066 fd: fildes
13067
13068Read eventfd value
13069[clinic start generated code]*/
13070
13071static PyObject *
13072os_eventfd_read_impl(PyObject *module, int fd)
13073/*[clinic end generated code: output=8f2c7b59a3521fd1 input=110f8b57fa596afe]*/
13074{
13075 eventfd_t value;
13076 int result;
13077 Py_BEGIN_ALLOW_THREADS
13078 result = eventfd_read(fd, &value);
13079 Py_END_ALLOW_THREADS
13080 if (result == -1) {
13081 return PyErr_SetFromErrno(PyExc_OSError);
13082 }
13083 return PyLong_FromUnsignedLongLong(value);
13084}
13085
13086/*[clinic input]
13087os.eventfd_write
13088
13089 fd: fildes
13090 value: unsigned_long_long
13091
13092Write eventfd value.
13093[clinic start generated code]*/
13094
13095static PyObject *
13096os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value)
13097/*[clinic end generated code: output=bebd9040bbf987f5 input=156de8555be5a949]*/
13098{
13099 int result;
13100 Py_BEGIN_ALLOW_THREADS
13101 result = eventfd_write(fd, value);
13102 Py_END_ALLOW_THREADS
13103 if (result == -1) {
13104 return PyErr_SetFromErrno(PyExc_OSError);
13105 }
13106 Py_RETURN_NONE;
13107}
13108#endif /* HAVE_EVENTFD */
13109
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013110/* Terminal size querying */
13111
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013112PyDoc_STRVAR(TerminalSize_docstring,
13113 "A tuple of (columns, lines) for holding terminal window size");
13114
13115static PyStructSequence_Field TerminalSize_fields[] = {
13116 {"columns", "width of the terminal window in characters"},
13117 {"lines", "height of the terminal window in characters"},
13118 {NULL, NULL}
13119};
13120
13121static PyStructSequence_Desc TerminalSize_desc = {
13122 "os.terminal_size",
13123 TerminalSize_docstring,
13124 TerminalSize_fields,
13125 2,
13126};
13127
13128#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013129/*[clinic input]
13130os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013131
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013132 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
13133 /
13134
13135Return the size of the terminal window as (columns, lines).
13136
13137The optional argument fd (default standard output) specifies
13138which file descriptor should be queried.
13139
13140If the file descriptor is not connected to a terminal, an OSError
13141is thrown.
13142
13143This function will only be defined if an implementation is
13144available for this system.
13145
13146shutil.get_terminal_size is the high-level function which should
13147normally be used, os.get_terminal_size is the low-level implementation.
13148[clinic start generated code]*/
13149
13150static PyObject *
13151os_get_terminal_size_impl(PyObject *module, int fd)
13152/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013153{
13154 int columns, lines;
13155 PyObject *termsize;
13156
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013157 /* Under some conditions stdout may not be connected and
13158 * fileno(stdout) may point to an invalid file descriptor. For example
13159 * GUI apps don't have valid standard streams by default.
13160 *
13161 * If this happens, and the optional fd argument is not present,
13162 * the ioctl below will fail returning EBADF. This is what we want.
13163 */
13164
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013165#ifdef TERMSIZE_USE_IOCTL
13166 {
13167 struct winsize w;
13168 if (ioctl(fd, TIOCGWINSZ, &w))
13169 return PyErr_SetFromErrno(PyExc_OSError);
13170 columns = w.ws_col;
13171 lines = w.ws_row;
13172 }
13173#endif /* TERMSIZE_USE_IOCTL */
13174
13175#ifdef TERMSIZE_USE_CONIO
13176 {
13177 DWORD nhandle;
13178 HANDLE handle;
13179 CONSOLE_SCREEN_BUFFER_INFO csbi;
13180 switch (fd) {
13181 case 0: nhandle = STD_INPUT_HANDLE;
13182 break;
13183 case 1: nhandle = STD_OUTPUT_HANDLE;
13184 break;
13185 case 2: nhandle = STD_ERROR_HANDLE;
13186 break;
13187 default:
13188 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
13189 }
13190 handle = GetStdHandle(nhandle);
13191 if (handle == NULL)
13192 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
13193 if (handle == INVALID_HANDLE_VALUE)
13194 return PyErr_SetFromWindowsErr(0);
13195
13196 if (!GetConsoleScreenBufferInfo(handle, &csbi))
13197 return PyErr_SetFromWindowsErr(0);
13198
13199 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
13200 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
13201 }
13202#endif /* TERMSIZE_USE_CONIO */
13203
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013204 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013205 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013206 if (termsize == NULL)
13207 return NULL;
13208 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
13209 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
13210 if (PyErr_Occurred()) {
13211 Py_DECREF(termsize);
13212 return NULL;
13213 }
13214 return termsize;
13215}
13216#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
13217
Larry Hastings2f936352014-08-05 14:04:04 +100013218
13219/*[clinic input]
13220os.cpu_count
13221
Charles-François Natali80d62e62015-08-13 20:37:08 +010013222Return the number of CPUs in the system; return None if indeterminable.
13223
13224This number is not equivalent to the number of CPUs the current process can
13225use. The number of usable CPUs can be obtained with
13226``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100013227[clinic start generated code]*/
13228
Larry Hastings2f936352014-08-05 14:04:04 +100013229static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013230os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013231/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013232{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013233 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013234#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010013235 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013236#elif defined(__hpux)
13237 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
13238#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
13239 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
pxinwr3405e052020-08-07 13:21:52 +080013240#elif defined(__VXWORKS__)
13241 ncpu = _Py_popcount32(vxCpuEnabledGet());
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013242#elif defined(__DragonFly__) || \
13243 defined(__OpenBSD__) || \
13244 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013245 defined(__NetBSD__) || \
13246 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020013247 int mib[2];
13248 size_t len = sizeof(ncpu);
13249 mib[0] = CTL_HW;
13250 mib[1] = HW_NCPU;
13251 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
13252 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013253#endif
13254 if (ncpu >= 1)
13255 return PyLong_FromLong(ncpu);
13256 else
13257 Py_RETURN_NONE;
13258}
13259
Victor Stinnerdaf45552013-08-28 00:53:59 +020013260
Larry Hastings2f936352014-08-05 14:04:04 +100013261/*[clinic input]
13262os.get_inheritable -> bool
13263
13264 fd: int
13265 /
13266
13267Get the close-on-exe flag of the specified file descriptor.
13268[clinic start generated code]*/
13269
Larry Hastings2f936352014-08-05 14:04:04 +100013270static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013271os_get_inheritable_impl(PyObject *module, int fd)
13272/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013273{
Steve Dower8fc89802015-04-12 00:26:27 -040013274 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040013275 _Py_BEGIN_SUPPRESS_IPH
13276 return_value = _Py_get_inheritable(fd);
13277 _Py_END_SUPPRESS_IPH
13278 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100013279}
13280
13281
13282/*[clinic input]
13283os.set_inheritable
13284 fd: int
13285 inheritable: int
13286 /
13287
13288Set the inheritable flag of the specified file descriptor.
13289[clinic start generated code]*/
13290
Larry Hastings2f936352014-08-05 14:04:04 +100013291static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013292os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
13293/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020013294{
Steve Dower8fc89802015-04-12 00:26:27 -040013295 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013296
Steve Dower8fc89802015-04-12 00:26:27 -040013297 _Py_BEGIN_SUPPRESS_IPH
13298 result = _Py_set_inheritable(fd, inheritable, NULL);
13299 _Py_END_SUPPRESS_IPH
13300 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020013301 return NULL;
13302 Py_RETURN_NONE;
13303}
13304
13305
13306#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100013307/*[clinic input]
13308os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070013309 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013310 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020013311
Larry Hastings2f936352014-08-05 14:04:04 +100013312Get the close-on-exe flag of the specified file descriptor.
13313[clinic start generated code]*/
13314
Larry Hastings2f936352014-08-05 14:04:04 +100013315static int
Benjamin Petersonca470632016-09-06 13:47:26 -070013316os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070013317/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013318{
13319 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013320
13321 if (!GetHandleInformation((HANDLE)handle, &flags)) {
13322 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100013323 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013324 }
13325
Larry Hastings2f936352014-08-05 14:04:04 +100013326 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013327}
13328
Victor Stinnerdaf45552013-08-28 00:53:59 +020013329
Larry Hastings2f936352014-08-05 14:04:04 +100013330/*[clinic input]
13331os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070013332 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013333 inheritable: bool
13334 /
13335
13336Set the inheritable flag of the specified handle.
13337[clinic start generated code]*/
13338
Larry Hastings2f936352014-08-05 14:04:04 +100013339static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070013340os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040013341 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070013342/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013343{
13344 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013345 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
13346 PyErr_SetFromWindowsErr(0);
13347 return NULL;
13348 }
13349 Py_RETURN_NONE;
13350}
Larry Hastings2f936352014-08-05 14:04:04 +100013351#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013352
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013353#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013354/*[clinic input]
13355os.get_blocking -> bool
13356 fd: int
13357 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013358
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013359Get the blocking mode of the file descriptor.
13360
13361Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
13362[clinic start generated code]*/
13363
13364static int
13365os_get_blocking_impl(PyObject *module, int fd)
13366/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013367{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013368 int blocking;
13369
Steve Dower8fc89802015-04-12 00:26:27 -040013370 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013371 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040013372 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013373 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013374}
13375
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013376/*[clinic input]
13377os.set_blocking
13378 fd: int
13379 blocking: bool(accept={int})
13380 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013381
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013382Set the blocking mode of the specified file descriptor.
13383
13384Set the O_NONBLOCK flag if blocking is False,
13385clear the O_NONBLOCK flag otherwise.
13386[clinic start generated code]*/
13387
13388static PyObject *
13389os_set_blocking_impl(PyObject *module, int fd, int blocking)
13390/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013391{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013392 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013393
Steve Dower8fc89802015-04-12 00:26:27 -040013394 _Py_BEGIN_SUPPRESS_IPH
13395 result = _Py_set_blocking(fd, blocking);
13396 _Py_END_SUPPRESS_IPH
13397 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013398 return NULL;
13399 Py_RETURN_NONE;
13400}
13401#endif /* !MS_WINDOWS */
13402
13403
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013404/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080013405class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013406[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080013407/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013408
13409typedef struct {
13410 PyObject_HEAD
13411 PyObject *name;
13412 PyObject *path;
13413 PyObject *stat;
13414 PyObject *lstat;
13415#ifdef MS_WINDOWS
13416 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010013417 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010013418 int got_file_index;
13419#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010013420#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013421 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013422#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013423 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013424 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010013425#endif
13426} DirEntry;
13427
13428static void
13429DirEntry_dealloc(DirEntry *entry)
13430{
Eddie Elizondob3966632019-11-05 07:16:14 -080013431 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010013432 Py_XDECREF(entry->name);
13433 Py_XDECREF(entry->path);
13434 Py_XDECREF(entry->stat);
13435 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080013436 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13437 free_func(entry);
13438 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013439}
13440
13441/* Forward reference */
13442static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013443DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13444 int follow_symlinks, unsigned short mode_bits);
Victor Stinner6036e442015-03-08 01:58:04 +010013445
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013446/*[clinic input]
13447os.DirEntry.is_symlink -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013448 defining_class: defining_class
13449 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013450
13451Return True if the entry is a symbolic link; cached per entry.
13452[clinic start generated code]*/
13453
Victor Stinner6036e442015-03-08 01:58:04 +010013454static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013455os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
13456/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013457{
13458#ifdef MS_WINDOWS
13459 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010013460#elif defined(HAVE_DIRENT_D_TYPE)
13461 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013462 if (self->d_type != DT_UNKNOWN)
13463 return self->d_type == DT_LNK;
13464 else
Victor Stinner97f33c32020-05-14 18:05:58 +020013465 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010013466#else
13467 /* POSIX without d_type */
Victor Stinner97f33c32020-05-14 18:05:58 +020013468 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010013469#endif
13470}
13471
13472static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013473DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
Victor Stinner6036e442015-03-08 01:58:04 +010013474{
13475 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013476 STRUCT_STAT st;
13477 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010013478
13479#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013480 if (!PyUnicode_FSDecoder(self->path, &ub))
13481 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013482#if USE_UNICODE_WCHAR_CACHE
13483_Py_COMP_DIAG_PUSH
13484_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013485 const wchar_t *path = PyUnicode_AsUnicode(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013486_Py_COMP_DIAG_POP
13487#else /* USE_UNICODE_WCHAR_CACHE */
13488 wchar_t *path = PyUnicode_AsWideCharString(ub, NULL);
13489 Py_DECREF(ub);
13490#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013491#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013492 if (!PyUnicode_FSConverter(self->path, &ub))
13493 return NULL;
13494 const char *path = PyBytes_AS_STRING(ub);
13495 if (self->dir_fd != DEFAULT_DIR_FD) {
13496#ifdef HAVE_FSTATAT
Ronald Oussoren41761932020-11-08 10:05:27 +010013497 if (HAVE_FSTATAT_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013498 result = fstatat(self->dir_fd, path, &st,
13499 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +010013500 } else
13501
13502#endif /* HAVE_FSTATAT */
13503 {
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013504 Py_DECREF(ub);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013505 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
13506 return NULL;
Ronald Oussoren41761932020-11-08 10:05:27 +010013507 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013508 }
13509 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013510#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013511 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013512 if (follow_symlinks)
13513 result = STAT(path, &st);
13514 else
13515 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013516 }
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013517#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE
13518 PyMem_Free(path);
13519#else /* USE_UNICODE_WCHAR_CACHE */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013520 Py_DECREF(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013521#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013522
13523 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013524 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013525
Victor Stinner97f33c32020-05-14 18:05:58 +020013526 return _pystat_fromstructstat(module, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010013527}
13528
13529static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013530DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
Victor Stinner6036e442015-03-08 01:58:04 +010013531{
13532 if (!self->lstat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013533 PyObject *module = PyType_GetModule(defining_class);
Victor Stinner6036e442015-03-08 01:58:04 +010013534#ifdef MS_WINDOWS
Victor Stinner97f33c32020-05-14 18:05:58 +020013535 self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010013536#else /* POSIX */
Victor Stinner97f33c32020-05-14 18:05:58 +020013537 self->lstat = DirEntry_fetch_stat(module, self, 0);
Victor Stinner6036e442015-03-08 01:58:04 +010013538#endif
13539 }
13540 Py_XINCREF(self->lstat);
13541 return self->lstat;
13542}
13543
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013544/*[clinic input]
13545os.DirEntry.stat
Victor Stinner97f33c32020-05-14 18:05:58 +020013546 defining_class: defining_class
13547 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013548 *
13549 follow_symlinks: bool = True
13550
13551Return stat_result object for the entry; cached per entry.
13552[clinic start generated code]*/
13553
Victor Stinner6036e442015-03-08 01:58:04 +010013554static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013555os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
13556 int follow_symlinks)
13557/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013558{
Victor Stinner97f33c32020-05-14 18:05:58 +020013559 if (!follow_symlinks) {
13560 return DirEntry_get_lstat(defining_class, self);
13561 }
Victor Stinner6036e442015-03-08 01:58:04 +010013562
13563 if (!self->stat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013564 int result = os_DirEntry_is_symlink_impl(self, defining_class);
13565 if (result == -1) {
Victor Stinner6036e442015-03-08 01:58:04 +010013566 return NULL;
Victor Stinner97f33c32020-05-14 18:05:58 +020013567 }
13568 if (result) {
13569 PyObject *module = PyType_GetModule(defining_class);
13570 self->stat = DirEntry_fetch_stat(module, self, 1);
13571 }
13572 else {
13573 self->stat = DirEntry_get_lstat(defining_class, self);
13574 }
Victor Stinner6036e442015-03-08 01:58:04 +010013575 }
13576
13577 Py_XINCREF(self->stat);
13578 return self->stat;
13579}
13580
Victor Stinner6036e442015-03-08 01:58:04 +010013581/* Set exception and return -1 on error, 0 for False, 1 for True */
13582static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013583DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13584 int follow_symlinks, unsigned short mode_bits)
Victor Stinner6036e442015-03-08 01:58:04 +010013585{
13586 PyObject *stat = NULL;
13587 PyObject *st_mode = NULL;
13588 long mode;
13589 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010013590#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013591 int is_symlink;
13592 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010013593#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013594#ifdef MS_WINDOWS
13595 unsigned long dir_bits;
13596#endif
13597
13598#ifdef MS_WINDOWS
13599 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
13600 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010013601#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013602 is_symlink = self->d_type == DT_LNK;
13603 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
13604#endif
13605
Victor Stinner35a97c02015-03-08 02:59:09 +010013606#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013607 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010013608#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020013609 stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010013610 if (!stat) {
13611 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
13612 /* If file doesn't exist (anymore), then return False
13613 (i.e., say it's not a file/directory) */
13614 PyErr_Clear();
13615 return 0;
13616 }
13617 goto error;
13618 }
Victor Stinner97f33c32020-05-14 18:05:58 +020013619 _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
13620 st_mode = PyObject_GetAttr(stat, state->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010013621 if (!st_mode)
13622 goto error;
13623
13624 mode = PyLong_AsLong(st_mode);
13625 if (mode == -1 && PyErr_Occurred())
13626 goto error;
13627 Py_CLEAR(st_mode);
13628 Py_CLEAR(stat);
13629 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010013630#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013631 }
13632 else if (is_symlink) {
13633 assert(mode_bits != S_IFLNK);
13634 result = 0;
13635 }
13636 else {
13637 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
13638#ifdef MS_WINDOWS
13639 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
13640 if (mode_bits == S_IFDIR)
13641 result = dir_bits != 0;
13642 else
13643 result = dir_bits == 0;
13644#else /* POSIX */
13645 if (mode_bits == S_IFDIR)
13646 result = self->d_type == DT_DIR;
13647 else
13648 result = self->d_type == DT_REG;
13649#endif
13650 }
Victor Stinner35a97c02015-03-08 02:59:09 +010013651#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013652
13653 return result;
13654
13655error:
13656 Py_XDECREF(st_mode);
13657 Py_XDECREF(stat);
13658 return -1;
13659}
13660
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013661/*[clinic input]
13662os.DirEntry.is_dir -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013663 defining_class: defining_class
13664 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013665 *
13666 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010013667
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013668Return True if the entry is a directory; cached per entry.
13669[clinic start generated code]*/
13670
13671static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013672os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
13673 int follow_symlinks)
13674/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013675{
Victor Stinner97f33c32020-05-14 18:05:58 +020013676 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010013677}
13678
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013679/*[clinic input]
13680os.DirEntry.is_file -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013681 defining_class: defining_class
13682 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013683 *
13684 follow_symlinks: bool = True
13685
13686Return True if the entry is a file; cached per entry.
13687[clinic start generated code]*/
13688
13689static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013690os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
13691 int follow_symlinks)
13692/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013693{
Victor Stinner97f33c32020-05-14 18:05:58 +020013694 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010013695}
13696
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013697/*[clinic input]
13698os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010013699
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013700Return inode of the entry; cached per entry.
13701[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013702
13703static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013704os_DirEntry_inode_impl(DirEntry *self)
13705/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013706{
13707#ifdef MS_WINDOWS
13708 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013709 PyObject *unicode;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013710 STRUCT_STAT stat;
13711 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010013712
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013713 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010013714 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013715#if USE_UNICODE_WCHAR_CACHE
13716_Py_COMP_DIAG_PUSH
13717_Py_COMP_DIAG_IGNORE_DEPR_DECLS
13718 const wchar_t *path = PyUnicode_AsUnicode(unicode);
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013719 result = LSTAT(path, &stat);
13720 Py_DECREF(unicode);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013721_Py_COMP_DIAG_POP
13722#else /* USE_UNICODE_WCHAR_CACHE */
13723 wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL);
13724 Py_DECREF(unicode);
13725 result = LSTAT(path, &stat);
13726 PyMem_Free(path);
13727#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013728
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013729 if (result != 0)
13730 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013731
13732 self->win32_file_index = stat.st_ino;
13733 self->got_file_index = 1;
13734 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013735 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13736 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013737#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013738 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13739 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013740#endif
13741}
13742
13743static PyObject *
13744DirEntry_repr(DirEntry *self)
13745{
13746 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13747}
13748
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013749/*[clinic input]
13750os.DirEntry.__fspath__
13751
13752Returns the path for the entry.
13753[clinic start generated code]*/
13754
Brett Cannon96881cd2016-06-10 14:37:21 -070013755static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013756os_DirEntry___fspath___impl(DirEntry *self)
13757/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013758{
13759 Py_INCREF(self->path);
13760 return self->path;
13761}
13762
Victor Stinner6036e442015-03-08 01:58:04 +010013763static PyMemberDef DirEntry_members[] = {
13764 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13765 "the entry's base filename, relative to scandir() \"path\" argument"},
13766 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13767 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13768 {NULL}
13769};
13770
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013771#include "clinic/posixmodule.c.h"
13772
Victor Stinner6036e442015-03-08 01:58:04 +010013773static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013774 OS_DIRENTRY_IS_DIR_METHODDEF
13775 OS_DIRENTRY_IS_FILE_METHODDEF
13776 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13777 OS_DIRENTRY_STAT_METHODDEF
13778 OS_DIRENTRY_INODE_METHODDEF
13779 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013780 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13781 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013782 {NULL}
13783};
13784
Eddie Elizondob3966632019-11-05 07:16:14 -080013785static PyType_Slot DirEntryType_slots[] = {
Eddie Elizondob3966632019-11-05 07:16:14 -080013786 {Py_tp_dealloc, DirEntry_dealloc},
13787 {Py_tp_repr, DirEntry_repr},
13788 {Py_tp_methods, DirEntry_methods},
13789 {Py_tp_members, DirEntry_members},
13790 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013791};
13792
Eddie Elizondob3966632019-11-05 07:16:14 -080013793static PyType_Spec DirEntryType_spec = {
13794 MODNAME ".DirEntry",
13795 sizeof(DirEntry),
13796 0,
Victor Stinner0cad0682021-04-30 14:06:49 +020013797 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
Eddie Elizondob3966632019-11-05 07:16:14 -080013798 DirEntryType_slots
13799};
13800
13801
Victor Stinner6036e442015-03-08 01:58:04 +010013802#ifdef MS_WINDOWS
13803
13804static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013805join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013806{
13807 Py_ssize_t path_len;
13808 Py_ssize_t size;
13809 wchar_t *result;
13810 wchar_t ch;
13811
13812 if (!path_wide) { /* Default arg: "." */
13813 path_wide = L".";
13814 path_len = 1;
13815 }
13816 else {
13817 path_len = wcslen(path_wide);
13818 }
13819
13820 /* The +1's are for the path separator and the NUL */
13821 size = path_len + 1 + wcslen(filename) + 1;
13822 result = PyMem_New(wchar_t, size);
13823 if (!result) {
13824 PyErr_NoMemory();
13825 return NULL;
13826 }
13827 wcscpy(result, path_wide);
13828 if (path_len > 0) {
13829 ch = result[path_len - 1];
13830 if (ch != SEP && ch != ALTSEP && ch != L':')
13831 result[path_len++] = SEP;
13832 wcscpy(result + path_len, filename);
13833 }
13834 return result;
13835}
13836
13837static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013838DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013839{
13840 DirEntry *entry;
13841 BY_HANDLE_FILE_INFORMATION file_info;
13842 ULONG reparse_tag;
13843 wchar_t *joined_path;
13844
Victor Stinner1c2fa782020-05-10 11:05:29 +020013845 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013846 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013847 if (!entry)
13848 return NULL;
13849 entry->name = NULL;
13850 entry->path = NULL;
13851 entry->stat = NULL;
13852 entry->lstat = NULL;
13853 entry->got_file_index = 0;
13854
13855 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13856 if (!entry->name)
13857 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013858 if (path->narrow) {
13859 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13860 if (!entry->name)
13861 goto error;
13862 }
Victor Stinner6036e442015-03-08 01:58:04 +010013863
13864 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13865 if (!joined_path)
13866 goto error;
13867
13868 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13869 PyMem_Free(joined_path);
13870 if (!entry->path)
13871 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013872 if (path->narrow) {
13873 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13874 if (!entry->path)
13875 goto error;
13876 }
Victor Stinner6036e442015-03-08 01:58:04 +010013877
Steve Dowercc16be82016-09-08 10:35:16 -070013878 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013879 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13880
13881 return (PyObject *)entry;
13882
13883error:
13884 Py_DECREF(entry);
13885 return NULL;
13886}
13887
13888#else /* POSIX */
13889
13890static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013891join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013892{
13893 Py_ssize_t path_len;
13894 Py_ssize_t size;
13895 char *result;
13896
13897 if (!path_narrow) { /* Default arg: "." */
13898 path_narrow = ".";
13899 path_len = 1;
13900 }
13901 else {
13902 path_len = strlen(path_narrow);
13903 }
13904
13905 if (filename_len == -1)
13906 filename_len = strlen(filename);
13907
13908 /* The +1's are for the path separator and the NUL */
13909 size = path_len + 1 + filename_len + 1;
13910 result = PyMem_New(char, size);
13911 if (!result) {
13912 PyErr_NoMemory();
13913 return NULL;
13914 }
13915 strcpy(result, path_narrow);
13916 if (path_len > 0 && result[path_len - 1] != '/')
13917 result[path_len++] = '/';
13918 strcpy(result + path_len, filename);
13919 return result;
13920}
13921
13922static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013923DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13924 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013925#ifdef HAVE_DIRENT_D_TYPE
13926 , unsigned char d_type
13927#endif
13928 )
Victor Stinner6036e442015-03-08 01:58:04 +010013929{
13930 DirEntry *entry;
13931 char *joined_path;
13932
Victor Stinner1c2fa782020-05-10 11:05:29 +020013933 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013934 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013935 if (!entry)
13936 return NULL;
13937 entry->name = NULL;
13938 entry->path = NULL;
13939 entry->stat = NULL;
13940 entry->lstat = NULL;
13941
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013942 if (path->fd != -1) {
13943 entry->dir_fd = path->fd;
13944 joined_path = NULL;
13945 }
13946 else {
13947 entry->dir_fd = DEFAULT_DIR_FD;
13948 joined_path = join_path_filename(path->narrow, name, name_len);
13949 if (!joined_path)
13950 goto error;
13951 }
Victor Stinner6036e442015-03-08 01:58:04 +010013952
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013953 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013954 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013955 if (joined_path)
13956 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013957 }
13958 else {
13959 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013960 if (joined_path)
13961 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013962 }
13963 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013964 if (!entry->name)
13965 goto error;
13966
13967 if (path->fd != -1) {
13968 entry->path = entry->name;
13969 Py_INCREF(entry->path);
13970 }
13971 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013972 goto error;
13973
Victor Stinner35a97c02015-03-08 02:59:09 +010013974#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013975 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013976#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013977 entry->d_ino = d_ino;
13978
13979 return (PyObject *)entry;
13980
13981error:
13982 Py_XDECREF(entry);
13983 return NULL;
13984}
13985
13986#endif
13987
13988
13989typedef struct {
13990 PyObject_HEAD
13991 path_t path;
13992#ifdef MS_WINDOWS
13993 HANDLE handle;
13994 WIN32_FIND_DATAW file_data;
13995 int first_time;
13996#else /* POSIX */
13997 DIR *dirp;
13998#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013999#ifdef HAVE_FDOPENDIR
14000 int fd;
14001#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014002} ScandirIterator;
14003
14004#ifdef MS_WINDOWS
14005
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014006static int
14007ScandirIterator_is_closed(ScandirIterator *iterator)
14008{
14009 return iterator->handle == INVALID_HANDLE_VALUE;
14010}
14011
Victor Stinner6036e442015-03-08 01:58:04 +010014012static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014013ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010014014{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014015 HANDLE handle = iterator->handle;
14016
14017 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010014018 return;
14019
Victor Stinner6036e442015-03-08 01:58:04 +010014020 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014021 Py_BEGIN_ALLOW_THREADS
14022 FindClose(handle);
14023 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010014024}
14025
14026static PyObject *
14027ScandirIterator_iternext(ScandirIterator *iterator)
14028{
14029 WIN32_FIND_DATAW *file_data = &iterator->file_data;
14030 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014031 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014032
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014033 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014034 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010014035 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014036
14037 while (1) {
14038 if (!iterator->first_time) {
14039 Py_BEGIN_ALLOW_THREADS
14040 success = FindNextFileW(iterator->handle, file_data);
14041 Py_END_ALLOW_THREADS
14042 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014043 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010014044 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014045 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010014046 break;
14047 }
14048 }
14049 iterator->first_time = 0;
14050
14051 /* Skip over . and .. */
14052 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020014053 wcscmp(file_data->cFileName, L"..") != 0)
14054 {
14055 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
14056 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014057 if (!entry)
14058 break;
14059 return entry;
14060 }
Victor Stinner6036e442015-03-08 01:58:04 +010014061
14062 /* Loop till we get a non-dot directory or finish iterating */
14063 }
14064
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014065 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014066 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010014067 return NULL;
14068}
14069
14070#else /* POSIX */
14071
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014072static int
14073ScandirIterator_is_closed(ScandirIterator *iterator)
14074{
14075 return !iterator->dirp;
14076}
14077
Victor Stinner6036e442015-03-08 01:58:04 +010014078static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014079ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010014080{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014081 DIR *dirp = iterator->dirp;
14082
14083 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010014084 return;
14085
Victor Stinner6036e442015-03-08 01:58:04 +010014086 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014087 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014088#ifdef HAVE_FDOPENDIR
14089 if (iterator->path.fd != -1)
14090 rewinddir(dirp);
14091#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014092 closedir(dirp);
14093 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010014094 return;
14095}
14096
14097static PyObject *
14098ScandirIterator_iternext(ScandirIterator *iterator)
14099{
14100 struct dirent *direntp;
14101 Py_ssize_t name_len;
14102 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014103 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014104
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014105 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014106 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010014107 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014108
14109 while (1) {
14110 errno = 0;
14111 Py_BEGIN_ALLOW_THREADS
14112 direntp = readdir(iterator->dirp);
14113 Py_END_ALLOW_THREADS
14114
14115 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014116 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010014117 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014118 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010014119 break;
14120 }
14121
14122 /* Skip over . and .. */
14123 name_len = NAMLEN(direntp);
14124 is_dot = direntp->d_name[0] == '.' &&
14125 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
14126 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014127 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
14128 entry = DirEntry_from_posix_info(module,
14129 &iterator->path, direntp->d_name,
14130 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010014131#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020014132 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010014133#endif
14134 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014135 if (!entry)
14136 break;
14137 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014138 }
14139
14140 /* Loop till we get a non-dot directory or finish iterating */
14141 }
14142
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014143 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014144 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010014145 return NULL;
14146}
14147
14148#endif
14149
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014150static PyObject *
14151ScandirIterator_close(ScandirIterator *self, PyObject *args)
14152{
14153 ScandirIterator_closedir(self);
14154 Py_RETURN_NONE;
14155}
14156
14157static PyObject *
14158ScandirIterator_enter(PyObject *self, PyObject *args)
14159{
14160 Py_INCREF(self);
14161 return self;
14162}
14163
14164static PyObject *
14165ScandirIterator_exit(ScandirIterator *self, PyObject *args)
14166{
14167 ScandirIterator_closedir(self);
14168 Py_RETURN_NONE;
14169}
14170
Victor Stinner6036e442015-03-08 01:58:04 +010014171static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010014172ScandirIterator_finalize(ScandirIterator *iterator)
14173{
14174 PyObject *error_type, *error_value, *error_traceback;
14175
14176 /* Save the current exception, if any. */
14177 PyErr_Fetch(&error_type, &error_value, &error_traceback);
14178
14179 if (!ScandirIterator_is_closed(iterator)) {
14180 ScandirIterator_closedir(iterator);
14181
14182 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
14183 "unclosed scandir iterator %R", iterator)) {
14184 /* Spurious errors can appear at shutdown */
14185 if (PyErr_ExceptionMatches(PyExc_Warning)) {
14186 PyErr_WriteUnraisable((PyObject *) iterator);
14187 }
14188 }
14189 }
14190
Victor Stinner7bfa4092016-03-23 00:43:54 +010014191 path_cleanup(&iterator->path);
14192
14193 /* Restore the saved exception. */
14194 PyErr_Restore(error_type, error_value, error_traceback);
14195}
14196
14197static void
Victor Stinner6036e442015-03-08 01:58:04 +010014198ScandirIterator_dealloc(ScandirIterator *iterator)
14199{
Eddie Elizondob3966632019-11-05 07:16:14 -080014200 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010014201 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
14202 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014203
Eddie Elizondob3966632019-11-05 07:16:14 -080014204 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
14205 free_func(iterator);
14206 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010014207}
14208
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014209static PyMethodDef ScandirIterator_methods[] = {
14210 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
14211 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
14212 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
14213 {NULL}
14214};
14215
Eddie Elizondob3966632019-11-05 07:16:14 -080014216static PyType_Slot ScandirIteratorType_slots[] = {
Eddie Elizondob3966632019-11-05 07:16:14 -080014217 {Py_tp_dealloc, ScandirIterator_dealloc},
14218 {Py_tp_finalize, ScandirIterator_finalize},
14219 {Py_tp_iter, PyObject_SelfIter},
14220 {Py_tp_iternext, ScandirIterator_iternext},
14221 {Py_tp_methods, ScandirIterator_methods},
14222 {0, 0},
14223};
14224
14225static PyType_Spec ScandirIteratorType_spec = {
14226 MODNAME ".ScandirIterator",
14227 sizeof(ScandirIterator),
14228 0,
Victor Stinner97f33c32020-05-14 18:05:58 +020014229 // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
14230 // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
Victor Stinner0cad0682021-04-30 14:06:49 +020014231 (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE
14232 | Py_TPFLAGS_DISALLOW_INSTANTIATION),
Eddie Elizondob3966632019-11-05 07:16:14 -080014233 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010014234};
14235
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014236/*[clinic input]
14237os.scandir
14238
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014239 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014240
14241Return an iterator of DirEntry objects for given path.
14242
BNMetricsb9427072018-11-02 15:20:19 +000014243path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014244is bytes, the names of yielded DirEntry objects will also be bytes; in
14245all other circumstances they will be str.
14246
14247If path is None, uses the path='.'.
14248[clinic start generated code]*/
14249
Victor Stinner6036e442015-03-08 01:58:04 +010014250static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014251os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000014252/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010014253{
14254 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010014255#ifdef MS_WINDOWS
14256 wchar_t *path_strW;
14257#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014258 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014259#ifdef HAVE_FDOPENDIR
14260 int fd = -1;
14261#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014262#endif
14263
Steve Dower60419a72019-06-24 08:42:54 -070014264 if (PySys_Audit("os.scandir", "O",
14265 path->object ? path->object : Py_None) < 0) {
14266 return NULL;
14267 }
14268
Hai Shif707d942020-03-16 21:15:01 +080014269 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014270 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010014271 if (!iterator)
14272 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014273
14274#ifdef MS_WINDOWS
14275 iterator->handle = INVALID_HANDLE_VALUE;
14276#else
14277 iterator->dirp = NULL;
14278#endif
14279
Serhiy Storchaka095ef732017-02-09 20:05:51 +020014280 /* Move the ownership to iterator->path */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014281 memcpy(&iterator->path, path, sizeof(path_t));
14282 memset(path, 0, sizeof(path_t));
Victor Stinner6036e442015-03-08 01:58:04 +010014283
14284#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010014285 iterator->first_time = 1;
14286
14287 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
14288 if (!path_strW)
14289 goto error;
14290
14291 Py_BEGIN_ALLOW_THREADS
14292 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
14293 Py_END_ALLOW_THREADS
14294
14295 PyMem_Free(path_strW);
14296
14297 if (iterator->handle == INVALID_HANDLE_VALUE) {
14298 path_error(&iterator->path);
14299 goto error;
14300 }
14301#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010014302 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014303#ifdef HAVE_FDOPENDIR
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014304 if (iterator->path.fd != -1) {
Ronald Oussoren41761932020-11-08 10:05:27 +010014305 if (HAVE_FDOPENDIR_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014306 /* closedir() closes the FD, so we duplicate it */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014307 fd = _Py_dup(iterator->path.fd);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014308 if (fd == -1)
14309 goto error;
14310
14311 Py_BEGIN_ALLOW_THREADS
14312 iterator->dirp = fdopendir(fd);
14313 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +010014314 } else {
14315 PyErr_SetString(PyExc_TypeError,
14316 "scandir: path should be string, bytes, os.PathLike or None, not int");
14317 return NULL;
14318 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014319 }
14320 else
14321#endif
14322 {
14323 if (iterator->path.narrow)
14324 path_str = iterator->path.narrow;
14325 else
14326 path_str = ".";
14327
14328 Py_BEGIN_ALLOW_THREADS
14329 iterator->dirp = opendir(path_str);
14330 Py_END_ALLOW_THREADS
14331 }
Victor Stinner6036e442015-03-08 01:58:04 +010014332
14333 if (!iterator->dirp) {
14334 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014335#ifdef HAVE_FDOPENDIR
14336 if (fd != -1) {
14337 Py_BEGIN_ALLOW_THREADS
14338 close(fd);
14339 Py_END_ALLOW_THREADS
14340 }
14341#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014342 goto error;
14343 }
14344#endif
14345
14346 return (PyObject *)iterator;
14347
14348error:
14349 Py_DECREF(iterator);
14350 return NULL;
14351}
14352
Ethan Furman410ef8e2016-06-04 12:06:26 -070014353/*
14354 Return the file system path representation of the object.
14355
14356 If the object is str or bytes, then allow it to pass through with
14357 an incremented refcount. If the object defines __fspath__(), then
14358 return the result of that method. All other types raise a TypeError.
14359*/
14360PyObject *
14361PyOS_FSPath(PyObject *path)
14362{
Brett Cannon3f9183b2016-08-26 14:44:48 -070014363 /* For error message reasons, this function is manually inlined in
14364 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070014365 PyObject *func = NULL;
14366 PyObject *path_repr = NULL;
14367
14368 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
14369 Py_INCREF(path);
14370 return path;
14371 }
14372
14373 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
14374 if (NULL == func) {
14375 return PyErr_Format(PyExc_TypeError,
14376 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014377 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080014378 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070014379 }
14380
Victor Stinnerf17c3de2016-12-06 18:46:19 +010014381 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070014382 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070014383 if (NULL == path_repr) {
14384 return NULL;
14385 }
14386
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014387 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
14388 PyErr_Format(PyExc_TypeError,
14389 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080014390 "not %.200s", _PyType_Name(Py_TYPE(path)),
14391 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014392 Py_DECREF(path_repr);
14393 return NULL;
14394 }
14395
Ethan Furman410ef8e2016-06-04 12:06:26 -070014396 return path_repr;
14397}
14398
14399/*[clinic input]
14400os.fspath
14401
14402 path: object
14403
14404Return the file system path representation of the object.
14405
Brett Cannonb4f43e92016-06-09 14:32:08 -070014406If the object is str or bytes, then allow it to pass through as-is. If the
14407object defines __fspath__(), then return the result of that method. All other
14408types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070014409[clinic start generated code]*/
14410
14411static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030014412os_fspath_impl(PyObject *module, PyObject *path)
14413/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070014414{
14415 return PyOS_FSPath(path);
14416}
Victor Stinner6036e442015-03-08 01:58:04 +010014417
Victor Stinner9b1f4742016-09-06 16:18:52 -070014418#ifdef HAVE_GETRANDOM_SYSCALL
14419/*[clinic input]
14420os.getrandom
14421
14422 size: Py_ssize_t
14423 flags: int=0
14424
14425Obtain a series of random bytes.
14426[clinic start generated code]*/
14427
14428static PyObject *
14429os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
14430/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
14431{
Victor Stinner9b1f4742016-09-06 16:18:52 -070014432 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014433 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014434
14435 if (size < 0) {
14436 errno = EINVAL;
14437 return posix_error();
14438 }
14439
Victor Stinnerec2319c2016-09-20 23:00:59 +020014440 bytes = PyBytes_FromStringAndSize(NULL, size);
14441 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014442 PyErr_NoMemory();
14443 return NULL;
14444 }
14445
14446 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014447 n = syscall(SYS_getrandom,
14448 PyBytes_AS_STRING(bytes),
14449 PyBytes_GET_SIZE(bytes),
14450 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070014451 if (n < 0 && errno == EINTR) {
14452 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014453 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014454 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020014455
14456 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070014457 continue;
14458 }
14459 break;
14460 }
14461
14462 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014463 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020014464 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014465 }
14466
Victor Stinnerec2319c2016-09-20 23:00:59 +020014467 if (n != size) {
14468 _PyBytes_Resize(&bytes, n);
14469 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070014470
14471 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014472
14473error:
14474 Py_DECREF(bytes);
14475 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014476}
14477#endif /* HAVE_GETRANDOM_SYSCALL */
14478
Steve Dower2438cdf2019-03-29 16:37:16 -070014479#ifdef MS_WINDOWS
14480/* bpo-36085: Helper functions for managing DLL search directories
14481 * on win32
14482 */
14483
14484typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
14485typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
14486
14487/*[clinic input]
14488os._add_dll_directory
14489
14490 path: path_t
14491
14492Add a path to the DLL search path.
14493
14494This search path is used when resolving dependencies for imported
14495extension modules (the module itself is resolved through sys.path),
14496and also by ctypes.
14497
14498Returns an opaque value that may be passed to os.remove_dll_directory
14499to remove this directory from the search path.
14500[clinic start generated code]*/
14501
14502static PyObject *
14503os__add_dll_directory_impl(PyObject *module, path_t *path)
14504/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
14505{
14506 HMODULE hKernel32;
14507 PAddDllDirectory AddDllDirectory;
14508 DLL_DIRECTORY_COOKIE cookie = 0;
14509 DWORD err = 0;
14510
Saiyang Gou7514f4f2020-02-12 23:47:42 -080014511 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
14512 return NULL;
14513 }
14514
Steve Dower2438cdf2019-03-29 16:37:16 -070014515 /* For Windows 7, we have to load this. As this will be a fairly
14516 infrequent operation, just do it each time. Kernel32 is always
14517 loaded. */
14518 Py_BEGIN_ALLOW_THREADS
14519 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14520 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
14521 hKernel32, "AddDllDirectory")) ||
14522 !(cookie = (*AddDllDirectory)(path->wide))) {
14523 err = GetLastError();
14524 }
14525 Py_END_ALLOW_THREADS
14526
14527 if (err) {
14528 return win32_error_object_err("add_dll_directory",
14529 path->object, err);
14530 }
14531
14532 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
14533}
14534
14535/*[clinic input]
14536os._remove_dll_directory
14537
14538 cookie: object
14539
14540Removes a path from the DLL search path.
14541
14542The parameter is an opaque value that was returned from
14543os.add_dll_directory. You can only remove directories that you added
14544yourself.
14545[clinic start generated code]*/
14546
14547static PyObject *
14548os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
14549/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
14550{
14551 HMODULE hKernel32;
14552 PRemoveDllDirectory RemoveDllDirectory;
14553 DLL_DIRECTORY_COOKIE cookieValue;
14554 DWORD err = 0;
14555
14556 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
14557 PyErr_SetString(PyExc_TypeError,
14558 "Provided cookie was not returned from os.add_dll_directory");
14559 return NULL;
14560 }
14561
14562 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
14563 cookie, "DLL directory cookie");
14564
14565 /* For Windows 7, we have to load this. As this will be a fairly
14566 infrequent operation, just do it each time. Kernel32 is always
14567 loaded. */
14568 Py_BEGIN_ALLOW_THREADS
14569 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14570 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
14571 hKernel32, "RemoveDllDirectory")) ||
14572 !(*RemoveDllDirectory)(cookieValue)) {
14573 err = GetLastError();
14574 }
14575 Py_END_ALLOW_THREADS
14576
14577 if (err) {
14578 return win32_error_object_err("remove_dll_directory",
14579 NULL, err);
14580 }
14581
14582 if (PyCapsule_SetName(cookie, NULL)) {
14583 return NULL;
14584 }
14585
14586 Py_RETURN_NONE;
14587}
14588
14589#endif
Larry Hastings31826802013-10-19 00:09:25 -070014590
Victor Stinner65a796e2020-04-01 18:49:29 +020014591
14592/* Only check if WIFEXITED is available: expect that it comes
14593 with WEXITSTATUS, WIFSIGNALED, etc.
14594
14595 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
14596 subprocess can safely call it during late Python finalization without
Victor Stinner62230712020-11-18 23:18:29 +010014597 risking that used os attributes were set to None by finalize_modules(). */
Victor Stinner65a796e2020-04-01 18:49:29 +020014598#if defined(WIFEXITED) || defined(MS_WINDOWS)
14599/*[clinic input]
14600os.waitstatus_to_exitcode
14601
Victor Stinner9bee32b2020-04-22 16:30:35 +020014602 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020014603
14604Convert a wait status to an exit code.
14605
14606On Unix:
14607
14608* If WIFEXITED(status) is true, return WEXITSTATUS(status).
14609* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
14610* Otherwise, raise a ValueError.
14611
14612On Windows, return status shifted right by 8 bits.
14613
14614On Unix, if the process is being traced or if waitpid() was called with
14615WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
14616This function must not be called if WIFSTOPPED(status) is true.
14617[clinic start generated code]*/
14618
14619static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020014620os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
14621/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020014622{
14623#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020014624 int status = _PyLong_AsInt(status_obj);
14625 if (status == -1 && PyErr_Occurred()) {
14626 return NULL;
14627 }
14628
Victor Stinner65a796e2020-04-01 18:49:29 +020014629 WAIT_TYPE wait_status;
14630 WAIT_STATUS_INT(wait_status) = status;
14631 int exitcode;
14632 if (WIFEXITED(wait_status)) {
14633 exitcode = WEXITSTATUS(wait_status);
14634 /* Sanity check to provide warranty on the function behavior.
14635 It should not occur in practice */
14636 if (exitcode < 0) {
14637 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
14638 return NULL;
14639 }
14640 }
14641 else if (WIFSIGNALED(wait_status)) {
14642 int signum = WTERMSIG(wait_status);
14643 /* Sanity check to provide warranty on the function behavior.
14644 It should not occurs in practice */
14645 if (signum <= 0) {
14646 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
14647 return NULL;
14648 }
14649 exitcode = -signum;
14650 } else if (WIFSTOPPED(wait_status)) {
14651 /* Status only received if the process is being traced
14652 or if waitpid() was called with WUNTRACED option. */
14653 int signum = WSTOPSIG(wait_status);
14654 PyErr_Format(PyExc_ValueError,
14655 "process stopped by delivery of signal %i",
14656 signum);
14657 return NULL;
14658 }
14659 else {
14660 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
14661 return NULL;
14662 }
14663 return PyLong_FromLong(exitcode);
14664#else
14665 /* Windows implementation: see os.waitpid() implementation
14666 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020014667 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
14668 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
14669 return NULL;
14670 }
14671
14672 unsigned long long exitcode = (status >> 8);
14673 /* ExitProcess() accepts an UINT type:
14674 reject exit code which doesn't fit in an UINT */
14675 if (exitcode > UINT_MAX) {
14676 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
14677 return NULL;
14678 }
14679 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020014680#endif
14681}
14682#endif
14683
14684
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014685static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070014686
14687 OS_STAT_METHODDEF
14688 OS_ACCESS_METHODDEF
14689 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014690 OS_CHDIR_METHODDEF
14691 OS_CHFLAGS_METHODDEF
14692 OS_CHMOD_METHODDEF
14693 OS_FCHMOD_METHODDEF
14694 OS_LCHMOD_METHODDEF
14695 OS_CHOWN_METHODDEF
14696 OS_FCHOWN_METHODDEF
14697 OS_LCHOWN_METHODDEF
14698 OS_LCHFLAGS_METHODDEF
14699 OS_CHROOT_METHODDEF
14700 OS_CTERMID_METHODDEF
14701 OS_GETCWD_METHODDEF
14702 OS_GETCWDB_METHODDEF
14703 OS_LINK_METHODDEF
14704 OS_LISTDIR_METHODDEF
14705 OS_LSTAT_METHODDEF
14706 OS_MKDIR_METHODDEF
14707 OS_NICE_METHODDEF
14708 OS_GETPRIORITY_METHODDEF
14709 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014710 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030014711 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014712 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010014713 OS_COPY_FILE_RANGE_METHODDEF
Pablo Galindoa57b3d32020-11-17 00:00:38 +000014714 OS_SPLICE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014715 OS_RENAME_METHODDEF
14716 OS_REPLACE_METHODDEF
14717 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014718 OS_SYMLINK_METHODDEF
14719 OS_SYSTEM_METHODDEF
14720 OS_UMASK_METHODDEF
14721 OS_UNAME_METHODDEF
14722 OS_UNLINK_METHODDEF
14723 OS_REMOVE_METHODDEF
14724 OS_UTIME_METHODDEF
14725 OS_TIMES_METHODDEF
14726 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014727 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014728 OS_EXECV_METHODDEF
14729 OS_EXECVE_METHODDEF
14730 OS_SPAWNV_METHODDEF
14731 OS_SPAWNVE_METHODDEF
14732 OS_FORK1_METHODDEF
14733 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014734 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014735 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14736 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14737 OS_SCHED_GETPARAM_METHODDEF
14738 OS_SCHED_GETSCHEDULER_METHODDEF
14739 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14740 OS_SCHED_SETPARAM_METHODDEF
14741 OS_SCHED_SETSCHEDULER_METHODDEF
14742 OS_SCHED_YIELD_METHODDEF
14743 OS_SCHED_SETAFFINITY_METHODDEF
14744 OS_SCHED_GETAFFINITY_METHODDEF
14745 OS_OPENPTY_METHODDEF
14746 OS_FORKPTY_METHODDEF
14747 OS_GETEGID_METHODDEF
14748 OS_GETEUID_METHODDEF
14749 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014750 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014751 OS_GETGROUPS_METHODDEF
14752 OS_GETPID_METHODDEF
14753 OS_GETPGRP_METHODDEF
14754 OS_GETPPID_METHODDEF
14755 OS_GETUID_METHODDEF
14756 OS_GETLOGIN_METHODDEF
14757 OS_KILL_METHODDEF
14758 OS_KILLPG_METHODDEF
14759 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014760 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014761 OS_SETUID_METHODDEF
14762 OS_SETEUID_METHODDEF
14763 OS_SETREUID_METHODDEF
14764 OS_SETGID_METHODDEF
14765 OS_SETEGID_METHODDEF
14766 OS_SETREGID_METHODDEF
14767 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014768 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014769 OS_GETPGID_METHODDEF
14770 OS_SETPGRP_METHODDEF
14771 OS_WAIT_METHODDEF
14772 OS_WAIT3_METHODDEF
14773 OS_WAIT4_METHODDEF
14774 OS_WAITID_METHODDEF
14775 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014776 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014777 OS_GETSID_METHODDEF
14778 OS_SETSID_METHODDEF
14779 OS_SETPGID_METHODDEF
14780 OS_TCGETPGRP_METHODDEF
14781 OS_TCSETPGRP_METHODDEF
14782 OS_OPEN_METHODDEF
14783 OS_CLOSE_METHODDEF
14784 OS_CLOSERANGE_METHODDEF
14785 OS_DEVICE_ENCODING_METHODDEF
14786 OS_DUP_METHODDEF
14787 OS_DUP2_METHODDEF
14788 OS_LOCKF_METHODDEF
14789 OS_LSEEK_METHODDEF
14790 OS_READ_METHODDEF
14791 OS_READV_METHODDEF
14792 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014793 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014794 OS_WRITE_METHODDEF
14795 OS_WRITEV_METHODDEF
14796 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014797 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014798 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014799 OS_FSTAT_METHODDEF
14800 OS_ISATTY_METHODDEF
14801 OS_PIPE_METHODDEF
14802 OS_PIPE2_METHODDEF
14803 OS_MKFIFO_METHODDEF
14804 OS_MKNOD_METHODDEF
14805 OS_MAJOR_METHODDEF
14806 OS_MINOR_METHODDEF
14807 OS_MAKEDEV_METHODDEF
14808 OS_FTRUNCATE_METHODDEF
14809 OS_TRUNCATE_METHODDEF
14810 OS_POSIX_FALLOCATE_METHODDEF
14811 OS_POSIX_FADVISE_METHODDEF
14812 OS_PUTENV_METHODDEF
14813 OS_UNSETENV_METHODDEF
14814 OS_STRERROR_METHODDEF
14815 OS_FCHDIR_METHODDEF
14816 OS_FSYNC_METHODDEF
14817 OS_SYNC_METHODDEF
14818 OS_FDATASYNC_METHODDEF
14819 OS_WCOREDUMP_METHODDEF
14820 OS_WIFCONTINUED_METHODDEF
14821 OS_WIFSTOPPED_METHODDEF
14822 OS_WIFSIGNALED_METHODDEF
14823 OS_WIFEXITED_METHODDEF
14824 OS_WEXITSTATUS_METHODDEF
14825 OS_WTERMSIG_METHODDEF
14826 OS_WSTOPSIG_METHODDEF
14827 OS_FSTATVFS_METHODDEF
14828 OS_STATVFS_METHODDEF
14829 OS_CONFSTR_METHODDEF
14830 OS_SYSCONF_METHODDEF
14831 OS_FPATHCONF_METHODDEF
14832 OS_PATHCONF_METHODDEF
14833 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014834 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014835 OS__GETDISKUSAGE_METHODDEF
14836 OS__GETFINALPATHNAME_METHODDEF
14837 OS__GETVOLUMEPATHNAME_METHODDEF
Steve Dower04732ca2021-04-07 01:02:07 +010014838 OS__PATH_SPLITROOT_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014839 OS_GETLOADAVG_METHODDEF
14840 OS_URANDOM_METHODDEF
14841 OS_SETRESUID_METHODDEF
14842 OS_SETRESGID_METHODDEF
14843 OS_GETRESUID_METHODDEF
14844 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014845
Larry Hastings2f936352014-08-05 14:04:04 +100014846 OS_GETXATTR_METHODDEF
14847 OS_SETXATTR_METHODDEF
14848 OS_REMOVEXATTR_METHODDEF
14849 OS_LISTXATTR_METHODDEF
14850
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014851 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014852 OS_CPU_COUNT_METHODDEF
14853 OS_GET_INHERITABLE_METHODDEF
14854 OS_SET_INHERITABLE_METHODDEF
14855 OS_GET_HANDLE_INHERITABLE_METHODDEF
14856 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014857 OS_GET_BLOCKING_METHODDEF
14858 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014859 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014860 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014861 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014862 OS_MEMFD_CREATE_METHODDEF
Christian Heimescd9fed62020-11-13 19:48:52 +010014863 OS_EVENTFD_METHODDEF
14864 OS_EVENTFD_READ_METHODDEF
14865 OS_EVENTFD_WRITE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014866 OS__ADD_DLL_DIRECTORY_METHODDEF
14867 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014868 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014869 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014870};
14871
Barry Warsaw4a342091996-12-19 23:50:02 +000014872static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014873all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014874{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014875#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014876 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014877#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014878#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014879 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014880#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014881#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014882 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014883#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014884#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014885 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014886#endif
Fred Drakec9680921999-12-13 16:37:25 +000014887#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014888 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014889#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014890#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014891 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014892#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014893#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014894 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014895#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014896#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014897 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014898#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014899#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014900 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014901#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014902#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014903 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014904#endif
14905#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014906 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014907#endif
14908#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014909 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014910#endif
14911#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014912 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014913#endif
14914#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014915 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014916#endif
14917#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014918 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014919#endif
14920#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014921 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014922#endif
14923#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014924 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014925#endif
14926#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014927 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014928#endif
14929#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014930 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014931#endif
14932#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014933 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014934#endif
14935#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014936 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014937#endif
14938#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014939 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014940#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014941#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014942 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014943#endif
14944#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014945 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014946#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014947#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014948 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014949#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014950#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014951 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014952#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014953#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014954#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014955 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014956#endif
14957#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014958 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014959#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014960#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014961#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014962 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014963#endif
14964#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014965 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014966#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014967#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014968 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014969#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014970#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014971 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014972#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014973#ifdef O_TMPFILE
14974 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14975#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014976#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014977 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014978#endif
14979#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014980 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014981#endif
14982#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014983 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014984#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014985#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014986 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014987#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014988#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014989 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014990#endif
Dong-hee Naf917c242021-02-04 08:32:55 +090014991#ifdef O_EVTONLY
14992 if (PyModule_AddIntMacro(m, O_EVTONLY)) return -1;
14993#endif
14994#ifdef O_FSYNC
14995 if (PyModule_AddIntMacro(m, O_FSYNC)) return -1;
14996#endif
14997#ifdef O_SYMLINK
14998 if (PyModule_AddIntMacro(m, O_SYMLINK)) return -1;
14999#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015000
Jesus Cea94363612012-06-22 18:32:07 +020015001#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015002 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020015003#endif
15004#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015005 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020015006#endif
15007
Tim Peters5aa91602002-01-30 05:46:57 +000015008/* MS Windows */
15009#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000015010 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015011 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000015012#endif
15013#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000015014 /* Optimize for short life (keep in memory). */
15015 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015016 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000015017#endif
15018#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000015019 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015020 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000015021#endif
15022#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000015023 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015024 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000015025#endif
15026#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000015027 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015028 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000015029#endif
15030
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015031/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000015032#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000015033 /* Send a SIGIO signal whenever input or output
15034 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015035 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000015036#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015037#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000015038 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015039 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015040#endif
15041#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000015042 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015043 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015044#endif
15045#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000015046 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015047 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015048#endif
Dong-hee Naf917c242021-02-04 08:32:55 +090015049#ifdef O_NOFOLLOW_ANY
15050 if (PyModule_AddIntMacro(m, O_NOFOLLOW_ANY)) return -1;
15051#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020015052#ifdef O_NOLINKS
15053 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015054 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020015055#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000015056#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000015057 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015058 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000015059#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000015060
Victor Stinner8c62be82010-05-06 00:08:46 +000015061 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015062#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015063 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015064#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015065#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015066 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015067#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015068#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015069 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015070#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015071#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015072 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015073#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015074#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015075 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015076#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015077#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015078 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015079#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015080#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015081 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015082#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015083#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015084 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015085#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015086#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015087 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015088#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015089#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015090 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015091#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015092#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015093 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015094#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015095#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015096 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015097#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015098#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015099 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015100#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015101#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015102 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015103#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015104#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015105 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015106#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015107#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015108 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015109#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015110#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015111 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015112#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015113
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000015114 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015115#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015116 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015117#endif /* ST_RDONLY */
15118#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015119 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015120#endif /* ST_NOSUID */
15121
doko@ubuntu.comca616a22013-12-08 15:23:07 +010015122 /* GNU extensions */
15123#ifdef ST_NODEV
15124 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
15125#endif /* ST_NODEV */
15126#ifdef ST_NOEXEC
15127 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
15128#endif /* ST_NOEXEC */
15129#ifdef ST_SYNCHRONOUS
15130 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
15131#endif /* ST_SYNCHRONOUS */
15132#ifdef ST_MANDLOCK
15133 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
15134#endif /* ST_MANDLOCK */
15135#ifdef ST_WRITE
15136 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
15137#endif /* ST_WRITE */
15138#ifdef ST_APPEND
15139 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
15140#endif /* ST_APPEND */
15141#ifdef ST_NOATIME
15142 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
15143#endif /* ST_NOATIME */
15144#ifdef ST_NODIRATIME
15145 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
15146#endif /* ST_NODIRATIME */
15147#ifdef ST_RELATIME
15148 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
15149#endif /* ST_RELATIME */
15150
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015151 /* FreeBSD sendfile() constants */
15152#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015153 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015154#endif
15155#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015156 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015157#endif
15158#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015159 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015160#endif
15161
Ross Lagerwall7807c352011-03-17 20:20:30 +020015162 /* constants for posix_fadvise */
15163#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015164 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015165#endif
15166#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015167 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015168#endif
15169#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015170 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015171#endif
15172#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015173 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015174#endif
15175#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015176 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015177#endif
15178#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015179 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015180#endif
15181
15182 /* constants for waitid */
15183#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015184 if (PyModule_AddIntMacro(m, P_PID)) return -1;
15185 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
15186 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080015187#ifdef P_PIDFD
15188 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
15189#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015190#endif
15191#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015192 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015193#endif
15194#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015195 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015196#endif
15197#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015198 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015199#endif
15200#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015201 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015202#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015203#ifdef CLD_KILLED
15204 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
15205#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015206#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015207 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015208#endif
15209#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015210 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015211#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015212#ifdef CLD_STOPPED
15213 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
15214#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015215#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015216 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015217#endif
15218
15219 /* constants for lockf */
15220#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015221 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015222#endif
15223#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015224 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015225#endif
15226#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015227 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015228#endif
15229#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015230 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015231#endif
15232
Pablo Galindo4defba32018-01-27 16:16:37 +000015233#ifdef RWF_DSYNC
15234 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
15235#endif
15236#ifdef RWF_HIPRI
15237 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
15238#endif
15239#ifdef RWF_SYNC
15240 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
15241#endif
15242#ifdef RWF_NOWAIT
15243 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
15244#endif
YoSTEALTH76ef2552020-05-27 15:32:22 -060015245#ifdef RWF_APPEND
15246 if (PyModule_AddIntConstant(m, "RWF_APPEND", RWF_APPEND)) return -1;
15247#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000015248
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015249/* constants for splice */
Pablo Galindo2a9eddf2020-11-17 19:57:49 +000015250#if defined(HAVE_SPLICE) && defined(__linux__)
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015251 if (PyModule_AddIntConstant(m, "SPLICE_F_MOVE", SPLICE_F_MOVE)) return -1;
15252 if (PyModule_AddIntConstant(m, "SPLICE_F_NONBLOCK", SPLICE_F_NONBLOCK)) return -1;
15253 if (PyModule_AddIntConstant(m, "SPLICE_F_MORE", SPLICE_F_MORE)) return -1;
15254#endif
15255
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000015256/* constants for posix_spawn */
15257#ifdef HAVE_POSIX_SPAWN
15258 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
15259 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
15260 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
15261#endif
15262
pxinwrf2d7ac72019-05-21 18:46:37 +080015263#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015264 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
15265 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015266 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080015267#endif
15268#ifdef HAVE_SPAWNV
15269 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015270 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000015271#endif
15272
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015273#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015274#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015275 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015276#endif
15277#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015278 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015279#endif
15280#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015281 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015282#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015283#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080015284 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015285#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015286#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015287 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015288#endif
15289#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015290 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015291#endif
15292#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015293 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015294#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015295#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015296 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015297#endif
15298#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015299 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015300#endif
15301#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015302 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015303#endif
15304#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015305 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015306#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015307#endif
15308
Benjamin Peterson9428d532011-09-14 11:45:52 -040015309#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015310 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
15311 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
15312 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015313#endif
15314
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015315#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015316 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015317#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015318#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015319 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015320#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015321#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015322 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015323#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015324#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015325 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015326#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015327#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015328 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015329#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015330#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015331 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015332#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015333#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015334 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015335#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010015336#if HAVE_DECL_RTLD_MEMBER
15337 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
15338#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020015339
Victor Stinner9b1f4742016-09-06 16:18:52 -070015340#ifdef HAVE_GETRANDOM_SYSCALL
15341 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
15342 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
15343#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015344#ifdef HAVE_MEMFD_CREATE
15345 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
15346 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
15347#ifdef MFD_HUGETLB
15348 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015349#endif
15350#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015351 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015352#endif
15353#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015354 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015355#endif
15356#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015357 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015358#endif
15359#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015360 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015361#endif
15362#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015363 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015364#endif
15365#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015366 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015367#endif
15368#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015369 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015370#endif
15371#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015372 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015373#endif
15374#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015375 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015376#endif
15377#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015378 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015379#endif
15380#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015381 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015382#endif
15383#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015384 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015385#endif
15386#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015387 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015388#endif
15389#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015390 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
15391#endif
Christian Heimescd9fed62020-11-13 19:48:52 +010015392#endif /* HAVE_MEMFD_CREATE */
15393
15394#ifdef HAVE_EVENTFD
15395 if (PyModule_AddIntMacro(m, EFD_CLOEXEC)) return -1;
15396 if (PyModule_AddIntMacro(m, EFD_NONBLOCK)) return -1;
15397 if (PyModule_AddIntMacro(m, EFD_SEMAPHORE)) return -1;
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015398#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070015399
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020015400#if defined(__APPLE__)
15401 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
15402#endif
15403
Steve Dower2438cdf2019-03-29 16:37:16 -070015404#ifdef MS_WINDOWS
15405 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
15406 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
15407 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
15408 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
15409 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
15410#endif
15411
Victor Stinner8c62be82010-05-06 00:08:46 +000015412 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000015413}
15414
15415
Ronald Oussoren41761932020-11-08 10:05:27 +010015416
15417#define PROBE(name, test) \
15418 static int name(void) \
15419 { \
15420 if (test) { \
15421 return 1; \
15422 } else { \
15423 return 0; \
15424 } \
15425 }
15426
15427#ifdef HAVE_FSTATAT
15428PROBE(probe_fstatat, HAVE_FSTATAT_RUNTIME)
15429#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070015430
15431#ifdef HAVE_FACCESSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015432PROBE(probe_faccessat, HAVE_FACCESSAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015433#endif
15434
15435#ifdef HAVE_FCHMODAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015436PROBE(probe_fchmodat, HAVE_FCHMODAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015437#endif
15438
Larry Hastings00964ed2013-08-12 13:49:30 -040015439#ifdef HAVE_FCHOWNAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015440PROBE(probe_fchownat, HAVE_FCHOWNAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015441#endif
15442
15443#ifdef HAVE_LINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015444PROBE(probe_linkat, HAVE_LINKAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015445#endif
15446
Ronald Oussoren41761932020-11-08 10:05:27 +010015447#ifdef HAVE_FDOPENDIR
15448PROBE(probe_fdopendir, HAVE_FDOPENDIR_RUNTIME)
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015449#endif
15450
Larry Hastings9cf065c2012-06-22 16:30:09 -070015451#ifdef HAVE_MKDIRAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015452PROBE(probe_mkdirat, HAVE_MKDIRAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015453#endif
15454
15455#ifdef HAVE_RENAMEAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015456PROBE(probe_renameat, HAVE_RENAMEAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015457#endif
15458
15459#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015460PROBE(probe_unlinkat, HAVE_UNLINKAT_RUNTIME)
15461#endif
15462
15463#ifdef HAVE_OPENAT
15464PROBE(probe_openat, HAVE_OPENAT_RUNTIME)
15465#endif
15466
15467#ifdef HAVE_READLINKAT
15468PROBE(probe_readlinkat, HAVE_READLINKAT_RUNTIME)
15469#endif
15470
15471#ifdef HAVE_SYMLINKAT
15472PROBE(probe_symlinkat, HAVE_SYMLINKAT_RUNTIME)
15473#endif
15474
15475#ifdef HAVE_FUTIMENS
15476PROBE(probe_futimens, HAVE_FUTIMENS_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015477#endif
15478
15479#ifdef HAVE_UTIMENSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015480PROBE(probe_utimensat, HAVE_UTIMENSAT_RUNTIME)
15481#endif
15482
15483
15484
15485
15486static const struct have_function {
15487 const char * const label;
15488 int (*probe)(void);
15489} have_functions[] = {
15490
Christian Heimescd9fed62020-11-13 19:48:52 +010015491#ifdef HAVE_EVENTFD
15492 {"HAVE_EVENTFD", NULL},
15493#endif
15494
Ronald Oussoren41761932020-11-08 10:05:27 +010015495#ifdef HAVE_FACCESSAT
15496 { "HAVE_FACCESSAT", probe_faccessat },
15497#endif
15498
15499#ifdef HAVE_FCHDIR
15500 { "HAVE_FCHDIR", NULL },
15501#endif
15502
15503#ifdef HAVE_FCHMOD
15504 { "HAVE_FCHMOD", NULL },
15505#endif
15506
15507#ifdef HAVE_FCHMODAT
15508 { "HAVE_FCHMODAT", probe_fchmodat },
15509#endif
15510
15511#ifdef HAVE_FCHOWN
15512 { "HAVE_FCHOWN", NULL },
15513#endif
15514
15515#ifdef HAVE_FCHOWNAT
15516 { "HAVE_FCHOWNAT", probe_fchownat },
15517#endif
15518
15519#ifdef HAVE_FEXECVE
15520 { "HAVE_FEXECVE", NULL },
15521#endif
15522
15523#ifdef HAVE_FDOPENDIR
15524 { "HAVE_FDOPENDIR", probe_fdopendir },
15525#endif
15526
15527#ifdef HAVE_FPATHCONF
15528 { "HAVE_FPATHCONF", NULL },
15529#endif
15530
15531#ifdef HAVE_FSTATAT
15532 { "HAVE_FSTATAT", probe_fstatat },
15533#endif
15534
15535#ifdef HAVE_FSTATVFS
15536 { "HAVE_FSTATVFS", NULL },
15537#endif
15538
15539#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
15540 { "HAVE_FTRUNCATE", NULL },
15541#endif
15542
15543#ifdef HAVE_FUTIMENS
15544 { "HAVE_FUTIMENS", probe_futimens },
15545#endif
15546
15547#ifdef HAVE_FUTIMES
15548 { "HAVE_FUTIMES", NULL },
15549#endif
15550
15551#ifdef HAVE_FUTIMESAT
15552 { "HAVE_FUTIMESAT", NULL },
15553#endif
15554
15555#ifdef HAVE_LINKAT
15556 { "HAVE_LINKAT", probe_linkat },
15557#endif
15558
15559#ifdef HAVE_LCHFLAGS
15560 { "HAVE_LCHFLAGS", NULL },
15561#endif
15562
15563#ifdef HAVE_LCHMOD
15564 { "HAVE_LCHMOD", NULL },
15565#endif
15566
15567#ifdef HAVE_LCHOWN
15568 { "HAVE_LCHOWN", NULL },
15569#endif
15570
15571#ifdef HAVE_LSTAT
15572 { "HAVE_LSTAT", NULL },
15573#endif
15574
15575#ifdef HAVE_LUTIMES
15576 { "HAVE_LUTIMES", NULL },
15577#endif
15578
15579#ifdef HAVE_MEMFD_CREATE
15580 { "HAVE_MEMFD_CREATE", NULL },
15581#endif
15582
15583#ifdef HAVE_MKDIRAT
15584 { "HAVE_MKDIRAT", probe_mkdirat },
15585#endif
15586
15587#ifdef HAVE_MKFIFOAT
15588 { "HAVE_MKFIFOAT", NULL },
15589#endif
15590
15591#ifdef HAVE_MKNODAT
15592 { "HAVE_MKNODAT", NULL },
15593#endif
15594
15595#ifdef HAVE_OPENAT
15596 { "HAVE_OPENAT", probe_openat },
15597#endif
15598
15599#ifdef HAVE_READLINKAT
15600 { "HAVE_READLINKAT", probe_readlinkat },
15601#endif
15602
15603#ifdef HAVE_RENAMEAT
15604 { "HAVE_RENAMEAT", probe_renameat },
15605#endif
15606
15607#ifdef HAVE_SYMLINKAT
15608 { "HAVE_SYMLINKAT", probe_symlinkat },
15609#endif
15610
15611#ifdef HAVE_UNLINKAT
15612 { "HAVE_UNLINKAT", probe_unlinkat },
15613#endif
15614
15615#ifdef HAVE_UTIMENSAT
15616 { "HAVE_UTIMENSAT", probe_utimensat },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015617#endif
15618
15619#ifdef MS_WINDOWS
Ronald Oussoren41761932020-11-08 10:05:27 +010015620 { "MS_WINDOWS", NULL },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015621#endif
15622
Ronald Oussoren41761932020-11-08 10:05:27 +010015623 { NULL, NULL }
Larry Hastings9cf065c2012-06-22 16:30:09 -070015624};
15625
15626
Victor Stinner1c2fa782020-05-10 11:05:29 +020015627static int
15628posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000015629{
Victor Stinner97f33c32020-05-14 18:05:58 +020015630 _posixstate *state = get_posix_state(m);
Tim Peters5aa91602002-01-30 05:46:57 +000015631
Ronald Oussoren41761932020-11-08 10:05:27 +010015632#if defined(HAVE_PWRITEV)
15633 if (HAVE_PWRITEV_RUNTIME) {} else {
15634 PyObject* dct = PyModule_GetDict(m);
15635
15636 if (dct == NULL) {
15637 return -1;
15638 }
15639
15640 if (PyDict_DelItemString(dct, "pwritev") == -1) {
15641 PyErr_Clear();
15642 }
15643 if (PyDict_DelItemString(dct, "preadv") == -1) {
15644 PyErr_Clear();
15645 }
15646 }
15647#endif
15648
Victor Stinner8c62be82010-05-06 00:08:46 +000015649 /* Initialize environ dictionary */
Victor Stinner97f33c32020-05-14 18:05:58 +020015650 PyObject *v = convertenviron();
Victor Stinner8c62be82010-05-06 00:08:46 +000015651 Py_XINCREF(v);
15652 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015653 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015654 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000015655
Victor Stinner8c62be82010-05-06 00:08:46 +000015656 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015657 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000015658
Victor Stinner8c62be82010-05-06 00:08:46 +000015659 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015660 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000015661
Victor Stinner8c62be82010-05-06 00:08:46 +000015662 Py_INCREF(PyExc_OSError);
15663 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000015664
Ross Lagerwall7807c352011-03-17 20:20:30 +020015665#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080015666 waitid_result_desc.name = MODNAME ".waitid_result";
15667 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
15668 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015669 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015670 }
15671 Py_INCREF(WaitidResultType);
15672 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015673 state->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015674#endif
15675
Eddie Elizondob3966632019-11-05 07:16:14 -080015676 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
15677 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
15678 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
15679 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
15680 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
15681 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015682 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015683 }
15684 Py_INCREF(StatResultType);
15685 PyModule_AddObject(m, "stat_result", StatResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015686 state->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015687 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
15688 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015689
Eddie Elizondob3966632019-11-05 07:16:14 -080015690 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
15691 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
15692 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015693 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015694 }
15695 Py_INCREF(StatVFSResultType);
15696 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015697 state->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015698#ifdef NEED_TICKS_PER_SECOND
15699# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080015700 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015701# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080015702 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015703# else
Eddie Elizondob3966632019-11-05 07:16:14 -080015704 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015705# endif
15706#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015707
William Orr81574b82018-10-01 22:19:56 -070015708#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080015709 sched_param_desc.name = MODNAME ".sched_param";
15710 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
15711 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015712 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015713 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015714 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080015715 PyModule_AddObject(m, "sched_param", SchedParamType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015716 state->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015717 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050015718#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000015719
Eddie Elizondob3966632019-11-05 07:16:14 -080015720 /* initialize TerminalSize_info */
15721 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
15722 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015723 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015724 }
15725 Py_INCREF(TerminalSizeType);
15726 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015727 state->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015728
15729 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020015730 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015731 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015732 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015733 }
Victor Stinner97f33c32020-05-14 18:05:58 +020015734 state->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015735
Victor Stinner1c2fa782020-05-10 11:05:29 +020015736 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015737 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015738 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015739 }
15740 Py_INCREF(DirEntryType);
15741 PyModule_AddObject(m, "DirEntry", DirEntryType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015742 state->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015743
Larry Hastings605a62d2012-06-24 04:33:36 -070015744 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080015745 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015746 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015747 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015748 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015749 Py_INCREF(TimesResultType);
15750 PyModule_AddObject(m, "times_result", TimesResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015751 state->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015752
Eddie Elizondob3966632019-11-05 07:16:14 -080015753 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015754 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015755 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015756 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015757 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015758 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015759 state->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015760
Victor Stinner97f33c32020-05-14 18:05:58 +020015761 if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015762 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015763#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +020015764 state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
15765 if (state->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015766 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015767#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020015768 state->st_mode = PyUnicode_InternFromString("st_mode");
15769 if (state->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015770 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070015771
Larry Hastings9cf065c2012-06-22 16:30:09 -070015772 /* suppress "function not used" warnings */
15773 {
15774 int ignored;
15775 fd_specified("", -1);
15776 follow_symlinks_specified("", 1);
15777 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
15778 dir_fd_converter(Py_None, &ignored);
15779 dir_fd_unavailable(Py_None, &ignored);
15780 }
15781
15782 /*
15783 * provide list of locally available functions
15784 * so os.py can populate support_* lists
15785 */
Victor Stinner97f33c32020-05-14 18:05:58 +020015786 PyObject *list = PyList_New(0);
15787 if (!list) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015788 return -1;
Victor Stinner97f33c32020-05-14 18:05:58 +020015789 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015790 for (const struct have_function *trace = have_functions; trace->label; trace++) {
15791 PyObject *unicode;
15792 if (trace->probe && !trace->probe()) continue;
15793 unicode = PyUnicode_DecodeASCII(trace->label, strlen(trace->label), NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015794 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015795 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015796 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015797 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015798 Py_DECREF(unicode);
15799 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015800
Larry Hastings9cf065c2012-06-22 16:30:09 -070015801 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040015802
Victor Stinner1c2fa782020-05-10 11:05:29 +020015803 return 0;
15804}
15805
15806
15807static PyModuleDef_Slot posixmodile_slots[] = {
15808 {Py_mod_exec, posixmodule_exec},
15809 {0, NULL}
15810};
15811
15812static struct PyModuleDef posixmodule = {
15813 PyModuleDef_HEAD_INIT,
15814 .m_name = MODNAME,
15815 .m_doc = posix__doc__,
15816 .m_size = sizeof(_posixstate),
15817 .m_methods = posix_methods,
15818 .m_slots = posixmodile_slots,
15819 .m_traverse = _posix_traverse,
15820 .m_clear = _posix_clear,
15821 .m_free = _posix_free,
15822};
15823
15824PyMODINIT_FUNC
15825INITFUNC(void)
15826{
15827 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015828}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015829
15830#ifdef __cplusplus
15831}
15832#endif