blob: 8ce62c88216e3d384154b8686383db37fe7f201a [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;
1854 hFindFile = FindFirstFileW(pszFile, &FileData);
1855 if (hFindFile == INVALID_HANDLE_VALUE)
1856 return FALSE;
1857 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001858 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001860}
1861
Brian Curtind25aef52011-06-13 15:16:04 -05001862static int
Steve Dowercc16be82016-09-08 10:35:16 -07001863win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001864 BOOL traverse)
1865{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001866 HANDLE hFile;
1867 BY_HANDLE_FILE_INFORMATION fileInfo;
1868 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1869 DWORD fileType, error;
1870 BOOL isUnhandledTag = FALSE;
1871 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001872
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001873 DWORD access = FILE_READ_ATTRIBUTES;
1874 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1875 if (!traverse) {
1876 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1877 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001878
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001879 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001880 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001881 /* Either the path doesn't exist, or the caller lacks access. */
1882 error = GetLastError();
1883 switch (error) {
1884 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1885 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1886 /* Try reading the parent directory. */
1887 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1888 /* Cannot read the parent directory. */
1889 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001890 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001891 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001892 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1893 if (traverse ||
1894 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1895 /* The stat call has to traverse but cannot, so fail. */
1896 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001897 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001898 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001899 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001900 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001901
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001902 case ERROR_INVALID_PARAMETER:
1903 /* \\.\con requires read or write access. */
1904 hFile = CreateFileW(path, access | GENERIC_READ,
1905 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1906 OPEN_EXISTING, flags, NULL);
1907 if (hFile == INVALID_HANDLE_VALUE) {
1908 SetLastError(error);
1909 return -1;
1910 }
1911 break;
1912
1913 case ERROR_CANT_ACCESS_FILE:
1914 /* bpo37834: open unhandled reparse points if traverse fails. */
1915 if (traverse) {
1916 traverse = FALSE;
1917 isUnhandledTag = TRUE;
1918 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1919 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1920 }
1921 if (hFile == INVALID_HANDLE_VALUE) {
1922 SetLastError(error);
1923 return -1;
1924 }
1925 break;
1926
1927 default:
1928 return -1;
1929 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001930 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001931
1932 if (hFile != INVALID_HANDLE_VALUE) {
1933 /* Handle types other than files on disk. */
1934 fileType = GetFileType(hFile);
1935 if (fileType != FILE_TYPE_DISK) {
1936 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1937 retval = -1;
1938 goto cleanup;
1939 }
1940 DWORD fileAttributes = GetFileAttributesW(path);
1941 memset(result, 0, sizeof(*result));
1942 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1943 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1944 /* \\.\pipe\ or \\.\mailslot\ */
1945 result->st_mode = _S_IFDIR;
1946 } else if (fileType == FILE_TYPE_CHAR) {
1947 /* \\.\nul */
1948 result->st_mode = _S_IFCHR;
1949 } else if (fileType == FILE_TYPE_PIPE) {
1950 /* \\.\pipe\spam */
1951 result->st_mode = _S_IFIFO;
1952 }
1953 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1954 goto cleanup;
1955 }
1956
1957 /* Query the reparse tag, and traverse a non-link. */
1958 if (!traverse) {
1959 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1960 &tagInfo, sizeof(tagInfo))) {
1961 /* Allow devices that do not support FileAttributeTagInfo. */
1962 switch (GetLastError()) {
1963 case ERROR_INVALID_PARAMETER:
1964 case ERROR_INVALID_FUNCTION:
1965 case ERROR_NOT_SUPPORTED:
1966 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1967 tagInfo.ReparseTag = 0;
1968 break;
1969 default:
1970 retval = -1;
1971 goto cleanup;
1972 }
1973 } else if (tagInfo.FileAttributes &
1974 FILE_ATTRIBUTE_REPARSE_POINT) {
1975 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1976 if (isUnhandledTag) {
1977 /* Traversing previously failed for either this link
1978 or its target. */
1979 SetLastError(ERROR_CANT_ACCESS_FILE);
1980 retval = -1;
1981 goto cleanup;
1982 }
1983 /* Traverse a non-link, but not if traversing already failed
1984 for an unhandled tag. */
1985 } else if (!isUnhandledTag) {
1986 CloseHandle(hFile);
1987 return win32_xstat_impl(path, result, TRUE);
1988 }
1989 }
1990 }
1991
1992 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1993 switch (GetLastError()) {
1994 case ERROR_INVALID_PARAMETER:
1995 case ERROR_INVALID_FUNCTION:
1996 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07001997 /* Volumes and physical disks are block devices, e.g.
1998 \\.\C: and \\.\PhysicalDrive0. */
1999 memset(result, 0, sizeof(*result));
2000 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002001 goto cleanup;
2002 }
Steve Dower772ec0f2019-09-04 14:42:54 -07002003 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002004 goto cleanup;
2005 }
2006 }
2007
2008 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
2009
2010 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
2011 /* Fix the file execute permissions. This hack sets S_IEXEC if
2012 the filename has an extension that is commonly used by files
2013 that CreateProcessW can execute. A real implementation calls
2014 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
2015 AccessCheck to check for generic read, write, and execute
2016 access. */
2017 const wchar_t *fileExtension = wcsrchr(path, '.');
2018 if (fileExtension) {
2019 if (_wcsicmp(fileExtension, L".exe") == 0 ||
2020 _wcsicmp(fileExtension, L".bat") == 0 ||
2021 _wcsicmp(fileExtension, L".cmd") == 0 ||
2022 _wcsicmp(fileExtension, L".com") == 0) {
2023 result->st_mode |= 0111;
2024 }
2025 }
2026 }
2027
2028cleanup:
2029 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07002030 /* Preserve last error if we are failing */
2031 error = retval ? GetLastError() : 0;
2032 if (!CloseHandle(hFile)) {
2033 retval = -1;
2034 } else if (retval) {
2035 /* Restore last error */
2036 SetLastError(error);
2037 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002038 }
2039
2040 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00002041}
2042
2043static int
Steve Dowercc16be82016-09-08 10:35:16 -07002044win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00002045{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002046 /* Protocol violation: we explicitly clear errno, instead of
2047 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05002048 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002049 errno = 0;
2050 return code;
2051}
Brian Curtind25aef52011-06-13 15:16:04 -05002052/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00002053
2054 In Posix, stat automatically traverses symlinks and returns the stat
2055 structure for the target. In Windows, the equivalent GetFileAttributes by
2056 default does not traverse symlinks and instead returns attributes for
2057 the symlink.
2058
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002059 Instead, we will open the file (which *does* traverse symlinks by default)
2060 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00002061
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002062static int
Steve Dowercc16be82016-09-08 10:35:16 -07002063win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00002064{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002065 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00002066}
2067
Victor Stinner8c62be82010-05-06 00:08:46 +00002068static int
Steve Dowercc16be82016-09-08 10:35:16 -07002069win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00002070{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002071 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00002072}
2073
Martin v. Löwis14694662006-02-03 12:54:16 +00002074#endif /* MS_WINDOWS */
2075
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002076PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002077"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002078This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002079 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002080or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
2081\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002082Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
2083or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002084\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002085See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002086
2087static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002088 {"st_mode", "protection bits"},
2089 {"st_ino", "inode"},
2090 {"st_dev", "device"},
2091 {"st_nlink", "number of hard links"},
2092 {"st_uid", "user ID of owner"},
2093 {"st_gid", "group ID of owner"},
2094 {"st_size", "total size, in bytes"},
2095 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
2096 {NULL, "integer time of last access"},
2097 {NULL, "integer time of last modification"},
2098 {NULL, "integer time of last change"},
2099 {"st_atime", "time of last access"},
2100 {"st_mtime", "time of last modification"},
2101 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07002102 {"st_atime_ns", "time of last access in nanoseconds"},
2103 {"st_mtime_ns", "time of last modification in nanoseconds"},
2104 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002105#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002106 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002107#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002108#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002109 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002110#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002111#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002112 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002113#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002114#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002115 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002116#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002117#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002118 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002119#endif
2120#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002121 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002122#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002123#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2124 {"st_file_attributes", "Windows file attribute bits"},
2125#endif
jcea6c51d512018-01-28 14:00:08 +01002126#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2127 {"st_fstype", "Type of filesystem"},
2128#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002129#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2130 {"st_reparse_tag", "Windows reparse tag"},
2131#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002132 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002133};
2134
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002135#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002136#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002137#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002138#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002139#endif
2140
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002141#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002142#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2143#else
2144#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2145#endif
2146
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002147#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002148#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2149#else
2150#define ST_RDEV_IDX ST_BLOCKS_IDX
2151#endif
2152
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002153#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2154#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2155#else
2156#define ST_FLAGS_IDX ST_RDEV_IDX
2157#endif
2158
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002159#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002160#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002161#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002162#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002163#endif
2164
2165#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2166#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2167#else
2168#define ST_BIRTHTIME_IDX ST_GEN_IDX
2169#endif
2170
Zachary Ware63f277b2014-06-19 09:46:37 -05002171#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2172#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2173#else
2174#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2175#endif
2176
jcea6c51d512018-01-28 14:00:08 +01002177#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2178#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2179#else
2180#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2181#endif
2182
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002183#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2184#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2185#else
2186#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2187#endif
2188
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002189static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002190 "stat_result", /* name */
2191 stat_result__doc__, /* doc */
2192 stat_result_fields,
2193 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002194};
2195
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002196PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002197"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2198This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002199 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002200or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002201\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002202See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002203
2204static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002205 {"f_bsize", },
2206 {"f_frsize", },
2207 {"f_blocks", },
2208 {"f_bfree", },
2209 {"f_bavail", },
2210 {"f_files", },
2211 {"f_ffree", },
2212 {"f_favail", },
2213 {"f_flag", },
2214 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002215 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002216 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002217};
2218
2219static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002220 "statvfs_result", /* name */
2221 statvfs_result__doc__, /* doc */
2222 statvfs_result_fields,
2223 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002224};
2225
Ross Lagerwall7807c352011-03-17 20:20:30 +02002226#if defined(HAVE_WAITID) && !defined(__APPLE__)
2227PyDoc_STRVAR(waitid_result__doc__,
2228"waitid_result: Result from waitid.\n\n\
2229This object may be accessed either as a tuple of\n\
2230 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2231or via the attributes si_pid, si_uid, and so on.\n\
2232\n\
2233See os.waitid for more information.");
2234
2235static PyStructSequence_Field waitid_result_fields[] = {
2236 {"si_pid", },
2237 {"si_uid", },
2238 {"si_signo", },
2239 {"si_status", },
2240 {"si_code", },
2241 {0}
2242};
2243
2244static PyStructSequence_Desc waitid_result_desc = {
2245 "waitid_result", /* name */
2246 waitid_result__doc__, /* doc */
2247 waitid_result_fields,
2248 5
2249};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002250#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002251static newfunc structseq_new;
2252
2253static PyObject *
2254statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2255{
Victor Stinner8c62be82010-05-06 00:08:46 +00002256 PyStructSequence *result;
2257 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002258
Victor Stinner8c62be82010-05-06 00:08:46 +00002259 result = (PyStructSequence*)structseq_new(type, args, kwds);
2260 if (!result)
2261 return NULL;
2262 /* If we have been initialized from a tuple,
2263 st_?time might be set to None. Initialize it
2264 from the int slots. */
2265 for (i = 7; i <= 9; i++) {
2266 if (result->ob_item[i+3] == Py_None) {
2267 Py_DECREF(Py_None);
2268 Py_INCREF(result->ob_item[i]);
2269 result->ob_item[i+3] = result->ob_item[i];
2270 }
2271 }
2272 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002273}
2274
Eddie Elizondob3966632019-11-05 07:16:14 -08002275static int
2276_posix_clear(PyObject *module)
2277{
Victor Stinner97f33c32020-05-14 18:05:58 +02002278 _posixstate *state = get_posix_state(module);
2279 Py_CLEAR(state->billion);
2280 Py_CLEAR(state->DirEntryType);
2281 Py_CLEAR(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002282#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002283 Py_CLEAR(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002284#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002285 Py_CLEAR(state->StatResultType);
2286 Py_CLEAR(state->StatVFSResultType);
2287 Py_CLEAR(state->TerminalSizeType);
2288 Py_CLEAR(state->TimesResultType);
2289 Py_CLEAR(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002290#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002291 Py_CLEAR(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002292#endif
2293#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002294 Py_CLEAR(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002295#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002296 Py_CLEAR(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002297 return 0;
2298}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002299
Eddie Elizondob3966632019-11-05 07:16:14 -08002300static int
2301_posix_traverse(PyObject *module, visitproc visit, void *arg)
2302{
Victor Stinner97f33c32020-05-14 18:05:58 +02002303 _posixstate *state = get_posix_state(module);
2304 Py_VISIT(state->billion);
2305 Py_VISIT(state->DirEntryType);
2306 Py_VISIT(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002307#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002308 Py_VISIT(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002309#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002310 Py_VISIT(state->StatResultType);
2311 Py_VISIT(state->StatVFSResultType);
2312 Py_VISIT(state->TerminalSizeType);
2313 Py_VISIT(state->TimesResultType);
2314 Py_VISIT(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002315#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002316 Py_VISIT(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002317#endif
2318#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002319 Py_VISIT(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002320#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002321 Py_VISIT(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002322 return 0;
2323}
2324
2325static void
2326_posix_free(void *module)
2327{
2328 _posix_clear((PyObject *)module);
2329}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002330
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002331static void
Victor Stinner1c2fa782020-05-10 11:05:29 +02002332fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002333{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002334 PyObject *s = _PyLong_FromTime_t(sec);
2335 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2336 PyObject *s_in_ns = NULL;
2337 PyObject *ns_total = NULL;
2338 PyObject *float_s = NULL;
2339
2340 if (!(s && ns_fractional))
2341 goto exit;
2342
Victor Stinner1c2fa782020-05-10 11:05:29 +02002343 s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002344 if (!s_in_ns)
2345 goto exit;
2346
2347 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2348 if (!ns_total)
2349 goto exit;
2350
Victor Stinner01b5aab2017-10-24 02:02:00 -07002351 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2352 if (!float_s) {
2353 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002354 }
2355
2356 PyStructSequence_SET_ITEM(v, index, s);
2357 PyStructSequence_SET_ITEM(v, index+3, float_s);
2358 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2359 s = NULL;
2360 float_s = NULL;
2361 ns_total = NULL;
2362exit:
2363 Py_XDECREF(s);
2364 Py_XDECREF(ns_fractional);
2365 Py_XDECREF(s_in_ns);
2366 Py_XDECREF(ns_total);
2367 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002368}
2369
Tim Peters5aa91602002-01-30 05:46:57 +00002370/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002371 (used by posix_stat() and posix_fstat()) */
2372static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +02002373_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002374{
Victor Stinner8c62be82010-05-06 00:08:46 +00002375 unsigned long ansec, mnsec, cnsec;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002376 PyObject *StatResultType = get_posix_state(module)->StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08002377 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002378 if (v == NULL)
2379 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002380
Victor Stinner8c62be82010-05-06 00:08:46 +00002381 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002382 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002383 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002384#ifdef MS_WINDOWS
2385 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002386#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002387 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002388#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002389 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002390#if defined(MS_WINDOWS)
2391 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2392 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2393#else
2394 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2395 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2396#endif
xdegaye50e86032017-05-22 11:15:08 +02002397 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2398 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002399
Martin v. Löwis14694662006-02-03 12:54:16 +00002400#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002401 ansec = st->st_atim.tv_nsec;
2402 mnsec = st->st_mtim.tv_nsec;
2403 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002404#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002405 ansec = st->st_atimespec.tv_nsec;
2406 mnsec = st->st_mtimespec.tv_nsec;
2407 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002408#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002409 ansec = st->st_atime_nsec;
2410 mnsec = st->st_mtime_nsec;
2411 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002412#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002413 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002414#endif
Victor Stinner1c2fa782020-05-10 11:05:29 +02002415 fill_time(module, v, 7, st->st_atime, ansec);
2416 fill_time(module, v, 8, st->st_mtime, mnsec);
2417 fill_time(module, v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002418
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002419#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002420 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2421 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002422#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002423#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002424 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2425 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002426#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002427#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002428 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2429 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002430#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002431#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002432 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2433 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002434#endif
2435#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002436 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002437 PyObject *val;
2438 unsigned long bsec,bnsec;
2439 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002440#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002441 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002442#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002443 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002444#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002445 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002446 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2447 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002448 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002449#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002450#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002451 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2452 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002453#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002454#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2455 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2456 PyLong_FromUnsignedLong(st->st_file_attributes));
2457#endif
jcea6c51d512018-01-28 14:00:08 +01002458#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2459 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2460 PyUnicode_FromString(st->st_fstype));
2461#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002462#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2463 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2464 PyLong_FromUnsignedLong(st->st_reparse_tag));
2465#endif
Fred Drake699f3522000-06-29 21:12:41 +00002466
Victor Stinner8c62be82010-05-06 00:08:46 +00002467 if (PyErr_Occurred()) {
2468 Py_DECREF(v);
2469 return NULL;
2470 }
Fred Drake699f3522000-06-29 21:12:41 +00002471
Victor Stinner8c62be82010-05-06 00:08:46 +00002472 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002473}
2474
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002475/* POSIX methods */
2476
Guido van Rossum94f6f721999-01-06 18:42:14 +00002477
2478static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02002479posix_do_stat(PyObject *module, const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002480 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002481{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002482 STRUCT_STAT st;
2483 int result;
2484
Ronald Oussoren41761932020-11-08 10:05:27 +01002485#ifdef HAVE_FSTATAT
2486 int fstatat_unavailable = 0;
2487#endif
2488
Larry Hastings9cf065c2012-06-22 16:30:09 -07002489#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2490 if (follow_symlinks_specified(function_name, follow_symlinks))
2491 return NULL;
2492#endif
2493
2494 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2495 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2496 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2497 return NULL;
2498
2499 Py_BEGIN_ALLOW_THREADS
2500 if (path->fd != -1)
2501 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002502#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002503 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002504 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002505 else
Steve Dowercc16be82016-09-08 10:35:16 -07002506 result = win32_lstat(path->wide, &st);
2507#else
2508 else
2509#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002510 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2511 result = LSTAT(path->narrow, &st);
2512 else
Steve Dowercc16be82016-09-08 10:35:16 -07002513#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002514#ifdef HAVE_FSTATAT
Ronald Oussoren41761932020-11-08 10:05:27 +01002515 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2516 if (HAVE_FSTATAT_RUNTIME) {
2517 result = fstatat(dir_fd, path->narrow, &st,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002518 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +01002519
2520 } else {
2521 fstatat_unavailable = 1;
2522 }
2523 } else
Steve Dowercc16be82016-09-08 10:35:16 -07002524#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002525 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002526#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002527 Py_END_ALLOW_THREADS
2528
Ronald Oussoren41761932020-11-08 10:05:27 +01002529#ifdef HAVE_FSTATAT
2530 if (fstatat_unavailable) {
2531 argument_unavailable_error("stat", "dir_fd");
2532 return NULL;
2533 }
2534#endif
2535
Victor Stinner292c8352012-10-30 02:17:38 +01002536 if (result != 0) {
2537 return path_error(path);
2538 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002539
Victor Stinner1c2fa782020-05-10 11:05:29 +02002540 return _pystat_fromstructstat(module, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002541}
2542
Larry Hastings2f936352014-08-05 14:04:04 +10002543/*[python input]
2544
2545for s in """
2546
2547FACCESSAT
2548FCHMODAT
2549FCHOWNAT
2550FSTATAT
2551LINKAT
2552MKDIRAT
2553MKFIFOAT
2554MKNODAT
2555OPENAT
2556READLINKAT
2557SYMLINKAT
2558UNLINKAT
2559
2560""".strip().split():
2561 s = s.strip()
2562 print("""
2563#ifdef HAVE_{s}
2564 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002565#else
Larry Hastings2f936352014-08-05 14:04:04 +10002566 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002567#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002568""".rstrip().format(s=s))
2569
2570for s in """
2571
2572FCHDIR
2573FCHMOD
2574FCHOWN
2575FDOPENDIR
2576FEXECVE
2577FPATHCONF
2578FSTATVFS
2579FTRUNCATE
2580
2581""".strip().split():
2582 s = s.strip()
2583 print("""
2584#ifdef HAVE_{s}
2585 #define PATH_HAVE_{s} 1
2586#else
2587 #define PATH_HAVE_{s} 0
2588#endif
2589
2590""".rstrip().format(s=s))
2591[python start generated code]*/
2592
2593#ifdef HAVE_FACCESSAT
2594 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2595#else
2596 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2597#endif
2598
2599#ifdef HAVE_FCHMODAT
2600 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2601#else
2602 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2603#endif
2604
2605#ifdef HAVE_FCHOWNAT
2606 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2607#else
2608 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2609#endif
2610
2611#ifdef HAVE_FSTATAT
2612 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2613#else
2614 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2615#endif
2616
2617#ifdef HAVE_LINKAT
2618 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2619#else
2620 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2621#endif
2622
2623#ifdef HAVE_MKDIRAT
2624 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2625#else
2626 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2627#endif
2628
2629#ifdef HAVE_MKFIFOAT
2630 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2631#else
2632 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2633#endif
2634
2635#ifdef HAVE_MKNODAT
2636 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2637#else
2638 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2639#endif
2640
2641#ifdef HAVE_OPENAT
2642 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2643#else
2644 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2645#endif
2646
2647#ifdef HAVE_READLINKAT
2648 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2649#else
2650 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2651#endif
2652
2653#ifdef HAVE_SYMLINKAT
2654 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2655#else
2656 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2657#endif
2658
2659#ifdef HAVE_UNLINKAT
2660 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2661#else
2662 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2663#endif
2664
2665#ifdef HAVE_FCHDIR
2666 #define PATH_HAVE_FCHDIR 1
2667#else
2668 #define PATH_HAVE_FCHDIR 0
2669#endif
2670
2671#ifdef HAVE_FCHMOD
2672 #define PATH_HAVE_FCHMOD 1
2673#else
2674 #define PATH_HAVE_FCHMOD 0
2675#endif
2676
2677#ifdef HAVE_FCHOWN
2678 #define PATH_HAVE_FCHOWN 1
2679#else
2680 #define PATH_HAVE_FCHOWN 0
2681#endif
2682
2683#ifdef HAVE_FDOPENDIR
2684 #define PATH_HAVE_FDOPENDIR 1
2685#else
2686 #define PATH_HAVE_FDOPENDIR 0
2687#endif
2688
2689#ifdef HAVE_FEXECVE
2690 #define PATH_HAVE_FEXECVE 1
2691#else
2692 #define PATH_HAVE_FEXECVE 0
2693#endif
2694
2695#ifdef HAVE_FPATHCONF
2696 #define PATH_HAVE_FPATHCONF 1
2697#else
2698 #define PATH_HAVE_FPATHCONF 0
2699#endif
2700
2701#ifdef HAVE_FSTATVFS
2702 #define PATH_HAVE_FSTATVFS 1
2703#else
2704 #define PATH_HAVE_FSTATVFS 0
2705#endif
2706
2707#ifdef HAVE_FTRUNCATE
2708 #define PATH_HAVE_FTRUNCATE 1
2709#else
2710 #define PATH_HAVE_FTRUNCATE 0
2711#endif
2712/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002713
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002714#ifdef MS_WINDOWS
2715 #undef PATH_HAVE_FTRUNCATE
2716 #define PATH_HAVE_FTRUNCATE 1
2717#endif
Larry Hastings31826802013-10-19 00:09:25 -07002718
Larry Hastings61272b72014-01-07 12:41:53 -08002719/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002720
2721class path_t_converter(CConverter):
2722
2723 type = "path_t"
2724 impl_by_reference = True
2725 parse_by_reference = True
2726
2727 converter = 'path_converter'
2728
2729 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002730 # right now path_t doesn't support default values.
2731 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002732 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002733 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002734
Larry Hastings2f936352014-08-05 14:04:04 +10002735 if self.c_default not in (None, 'Py_None'):
2736 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002737
2738 self.nullable = nullable
2739 self.allow_fd = allow_fd
2740
Larry Hastings7726ac92014-01-31 22:03:12 -08002741 def pre_render(self):
2742 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002743 if isinstance(value, str):
2744 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002745 return str(int(bool(value)))
2746
2747 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002748 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002749 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002750 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002751 strify(self.nullable),
2752 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002753 )
2754
2755 def cleanup(self):
2756 return "path_cleanup(&" + self.name + ");\n"
2757
2758
2759class dir_fd_converter(CConverter):
2760 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002761
Larry Hastings2f936352014-08-05 14:04:04 +10002762 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002763 if self.default in (unspecified, None):
2764 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002765 if isinstance(requires, str):
2766 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2767 else:
2768 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002769
Larry Hastings2f936352014-08-05 14:04:04 +10002770class uid_t_converter(CConverter):
2771 type = "uid_t"
2772 converter = '_Py_Uid_Converter'
2773
2774class gid_t_converter(CConverter):
2775 type = "gid_t"
2776 converter = '_Py_Gid_Converter'
2777
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002778class dev_t_converter(CConverter):
2779 type = 'dev_t'
2780 converter = '_Py_Dev_Converter'
2781
2782class dev_t_return_converter(unsigned_long_return_converter):
2783 type = 'dev_t'
2784 conversion_fn = '_PyLong_FromDev'
2785 unsigned_cast = '(dev_t)'
2786
Larry Hastings2f936352014-08-05 14:04:04 +10002787class FSConverter_converter(CConverter):
2788 type = 'PyObject *'
2789 converter = 'PyUnicode_FSConverter'
2790 def converter_init(self):
2791 if self.default is not unspecified:
2792 fail("FSConverter_converter does not support default values")
2793 self.c_default = 'NULL'
2794
2795 def cleanup(self):
2796 return "Py_XDECREF(" + self.name + ");\n"
2797
2798class pid_t_converter(CConverter):
2799 type = 'pid_t'
2800 format_unit = '" _Py_PARSE_PID "'
2801
2802class idtype_t_converter(int_converter):
2803 type = 'idtype_t'
2804
2805class id_t_converter(CConverter):
2806 type = 'id_t'
2807 format_unit = '" _Py_PARSE_PID "'
2808
Benjamin Petersonca470632016-09-06 13:47:26 -07002809class intptr_t_converter(CConverter):
2810 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002811 format_unit = '" _Py_PARSE_INTPTR "'
2812
2813class Py_off_t_converter(CConverter):
2814 type = 'Py_off_t'
2815 converter = 'Py_off_t_converter'
2816
2817class Py_off_t_return_converter(long_return_converter):
2818 type = 'Py_off_t'
2819 conversion_fn = 'PyLong_FromPy_off_t'
2820
2821class path_confname_converter(CConverter):
2822 type="int"
2823 converter="conv_path_confname"
2824
2825class confstr_confname_converter(path_confname_converter):
2826 converter='conv_confstr_confname'
2827
2828class sysconf_confname_converter(path_confname_converter):
2829 converter="conv_sysconf_confname"
2830
Larry Hastings61272b72014-01-07 12:41:53 -08002831[python start generated code]*/
Serhiy Storchaka9975cc52020-10-09 23:00:45 +03002832/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/
Larry Hastings31826802013-10-19 00:09:25 -07002833
Larry Hastings61272b72014-01-07 12:41:53 -08002834/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002835
Larry Hastings2a727912014-01-16 11:32:01 -08002836os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002837
2838 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002839 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002840 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002841
2842 *
2843
Larry Hastings2f936352014-08-05 14:04:04 +10002844 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002845 If not None, it should be a file descriptor open to a directory,
2846 and path should be a relative string; path will then be relative to
2847 that directory.
2848
2849 follow_symlinks: bool = True
2850 If False, and the last element of the path is a symbolic link,
2851 stat will examine the symbolic link itself instead of the file
2852 the link points to.
2853
2854Perform a stat system call on the given path.
2855
2856dir_fd and follow_symlinks may not be implemented
2857 on your platform. If they are unavailable, using them will raise a
2858 NotImplementedError.
2859
2860It's an error to use dir_fd or follow_symlinks when specifying path as
2861 an open file descriptor.
2862
Larry Hastings61272b72014-01-07 12:41:53 -08002863[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002864
Larry Hastings31826802013-10-19 00:09:25 -07002865static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002866os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002867/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002868{
Victor Stinner1c2fa782020-05-10 11:05:29 +02002869 return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002870}
2871
Larry Hastings2f936352014-08-05 14:04:04 +10002872
2873/*[clinic input]
2874os.lstat
2875
2876 path : path_t
2877
2878 *
2879
2880 dir_fd : dir_fd(requires='fstatat') = None
2881
2882Perform a stat system call on the given path, without following symbolic links.
2883
2884Like stat(), but do not follow symbolic links.
2885Equivalent to stat(path, follow_symlinks=False).
2886[clinic start generated code]*/
2887
Larry Hastings2f936352014-08-05 14:04:04 +10002888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002889os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2890/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002891{
2892 int follow_symlinks = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002893 return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10002894}
Larry Hastings31826802013-10-19 00:09:25 -07002895
Larry Hastings2f936352014-08-05 14:04:04 +10002896
Larry Hastings61272b72014-01-07 12:41:53 -08002897/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002898os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002899
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002900 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002901 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002902
2903 mode: int
2904 Operating-system mode bitfield. Can be F_OK to test existence,
2905 or the inclusive-OR of R_OK, W_OK, and X_OK.
2906
2907 *
2908
Larry Hastings2f936352014-08-05 14:04:04 +10002909 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002910 If not None, it should be a file descriptor open to a directory,
2911 and path should be relative; path will then be relative to that
2912 directory.
2913
2914 effective_ids: bool = False
2915 If True, access will use the effective uid/gid instead of
2916 the real uid/gid.
2917
2918 follow_symlinks: bool = True
2919 If False, and the last element of the path is a symbolic link,
2920 access will examine the symbolic link itself instead of the file
2921 the link points to.
2922
2923Use the real uid/gid to test for access to a path.
2924
2925{parameters}
2926dir_fd, effective_ids, and follow_symlinks may not be implemented
2927 on your platform. If they are unavailable, using them will raise a
2928 NotImplementedError.
2929
2930Note that most operations will use the effective uid/gid, therefore this
2931 routine can be used in a suid/sgid environment to test if the invoking user
2932 has the specified access to the path.
2933
Larry Hastings61272b72014-01-07 12:41:53 -08002934[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002935
Larry Hastings2f936352014-08-05 14:04:04 +10002936static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002937os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002938 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002939/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002940{
Larry Hastings2f936352014-08-05 14:04:04 +10002941 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002942
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002943#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002944 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002945#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002946 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002947#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002948
Ronald Oussoren41761932020-11-08 10:05:27 +01002949#ifdef HAVE_FACCESSAT
2950 int faccessat_unavailable = 0;
2951#endif
2952
Larry Hastings9cf065c2012-06-22 16:30:09 -07002953#ifndef HAVE_FACCESSAT
2954 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002955 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002956
2957 if (effective_ids) {
2958 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002959 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002960 }
2961#endif
2962
2963#ifdef MS_WINDOWS
2964 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002965 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002966 Py_END_ALLOW_THREADS
2967
2968 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002969 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002970 * * we didn't get a -1, and
2971 * * write access wasn't requested,
2972 * * or the file isn't read-only,
2973 * * or it's a directory.
2974 * (Directories cannot be read-only on Windows.)
2975 */
Larry Hastings2f936352014-08-05 14:04:04 +10002976 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002977 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002978 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002979 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002980#else
2981
2982 Py_BEGIN_ALLOW_THREADS
2983#ifdef HAVE_FACCESSAT
2984 if ((dir_fd != DEFAULT_DIR_FD) ||
2985 effective_ids ||
2986 !follow_symlinks) {
Ronald Oussoren41761932020-11-08 10:05:27 +01002987
2988 if (HAVE_FACCESSAT_RUNTIME) {
2989 int flags = 0;
2990 if (!follow_symlinks)
2991 flags |= AT_SYMLINK_NOFOLLOW;
2992 if (effective_ids)
2993 flags |= AT_EACCESS;
2994 result = faccessat(dir_fd, path->narrow, mode, flags);
2995 } else {
2996 faccessat_unavailable = 1;
2997 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002998 }
2999 else
3000#endif
Larry Hastings31826802013-10-19 00:09:25 -07003001 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003002 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01003003
3004#ifdef HAVE_FACCESSAT
3005 if (faccessat_unavailable) {
3006 if (dir_fd != DEFAULT_DIR_FD) {
3007 argument_unavailable_error("access", "dir_fd");
3008 return -1;
3009 }
3010 if (follow_symlinks_specified("access", follow_symlinks))
3011 return -1;
3012
3013 if (effective_ids) {
3014 argument_unavailable_error("access", "effective_ids");
3015 return -1;
3016 }
3017 /* should be unreachable */
3018 return -1;
3019 }
3020#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003021 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003022#endif
3023
Larry Hastings9cf065c2012-06-22 16:30:09 -07003024 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003025}
3026
Guido van Rossumd371ff11999-01-25 16:12:23 +00003027#ifndef F_OK
3028#define F_OK 0
3029#endif
3030#ifndef R_OK
3031#define R_OK 4
3032#endif
3033#ifndef W_OK
3034#define W_OK 2
3035#endif
3036#ifndef X_OK
3037#define X_OK 1
3038#endif
3039
Larry Hastings31826802013-10-19 00:09:25 -07003040
Guido van Rossumd371ff11999-01-25 16:12:23 +00003041#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08003042/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003043os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07003044
3045 fd: int
3046 Integer file descriptor handle.
3047
3048 /
3049
3050Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08003051[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07003052
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003053static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003054os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003055/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07003056{
Guido van Rossum94f6f721999-01-06 18:42:14 +00003057
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02003058 long size = sysconf(_SC_TTY_NAME_MAX);
3059 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003060 return posix_error();
3061 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02003062 char *buffer = (char *)PyMem_RawMalloc(size);
3063 if (buffer == NULL) {
3064 return PyErr_NoMemory();
3065 }
3066 int ret = ttyname_r(fd, buffer, size);
3067 if (ret != 0) {
3068 PyMem_RawFree(buffer);
3069 errno = ret;
3070 return posix_error();
3071 }
3072 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
3073 PyMem_RawFree(buffer);
3074 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003075}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003076#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003077
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003078#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10003079/*[clinic input]
3080os.ctermid
3081
3082Return the name of the controlling terminal for this process.
3083[clinic start generated code]*/
3084
Larry Hastings2f936352014-08-05 14:04:04 +10003085static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003086os_ctermid_impl(PyObject *module)
3087/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003088{
Victor Stinner8c62be82010-05-06 00:08:46 +00003089 char *ret;
3090 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003091
Greg Wardb48bc172000-03-01 21:51:56 +00003092#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00003093 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003094#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003095 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003096#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003097 if (ret == NULL)
3098 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00003099 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003100}
Larry Hastings2f936352014-08-05 14:04:04 +10003101#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003102
Larry Hastings2f936352014-08-05 14:04:04 +10003103
3104/*[clinic input]
3105os.chdir
3106
3107 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
3108
3109Change the current working directory to the specified path.
3110
3111path may always be specified as a string.
3112On some platforms, path may also be specified as an open file descriptor.
3113 If this functionality is unavailable, using it raises an exception.
3114[clinic start generated code]*/
3115
Larry Hastings2f936352014-08-05 14:04:04 +10003116static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003117os_chdir_impl(PyObject *module, path_t *path)
3118/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003119{
3120 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003121
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003122 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
3123 return NULL;
3124 }
3125
Larry Hastings9cf065c2012-06-22 16:30:09 -07003126 Py_BEGIN_ALLOW_THREADS
3127#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003128 /* on unix, success = 0, on windows, success = !0 */
3129 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003130#else
3131#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10003132 if (path->fd != -1)
3133 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003134 else
3135#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003136 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003137#endif
3138 Py_END_ALLOW_THREADS
3139
3140 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003141 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003142 }
3143
Larry Hastings2f936352014-08-05 14:04:04 +10003144 Py_RETURN_NONE;
3145}
3146
3147
3148#ifdef HAVE_FCHDIR
3149/*[clinic input]
3150os.fchdir
3151
3152 fd: fildes
3153
3154Change to the directory of the given file descriptor.
3155
3156fd must be opened on a directory, not a file.
3157Equivalent to os.chdir(fd).
3158
3159[clinic start generated code]*/
3160
Fred Drake4d1e64b2002-04-15 19:40:07 +00003161static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003162os_fchdir_impl(PyObject *module, int fd)
3163/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00003164{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003165 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
3166 return NULL;
3167 }
Larry Hastings2f936352014-08-05 14:04:04 +10003168 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00003169}
3170#endif /* HAVE_FCHDIR */
3171
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003172
Larry Hastings2f936352014-08-05 14:04:04 +10003173/*[clinic input]
3174os.chmod
3175
3176 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00003177 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10003178 On some platforms, path may also be specified as an open file descriptor.
3179 If this functionality is unavailable, using it raises an exception.
3180
3181 mode: int
3182 Operating-system mode bitfield.
3183
3184 *
3185
3186 dir_fd : dir_fd(requires='fchmodat') = None
3187 If not None, it should be a file descriptor open to a directory,
3188 and path should be relative; path will then be relative to that
3189 directory.
3190
3191 follow_symlinks: bool = True
3192 If False, and the last element of the path is a symbolic link,
3193 chmod will modify the symbolic link itself instead of the file
3194 the link points to.
3195
3196Change the access permissions of a file.
3197
3198It is an error to use dir_fd or follow_symlinks when specifying path as
3199 an open file descriptor.
3200dir_fd and follow_symlinks may not be implemented on your platform.
3201 If they are unavailable, using them will raise a NotImplementedError.
3202
3203[clinic start generated code]*/
3204
Larry Hastings2f936352014-08-05 14:04:04 +10003205static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003206os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003207 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003208/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003209{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003210 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003211
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003212#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003213 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003214#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003215
Larry Hastings9cf065c2012-06-22 16:30:09 -07003216#ifdef HAVE_FCHMODAT
3217 int fchmodat_nofollow_unsupported = 0;
Ronald Oussoren41761932020-11-08 10:05:27 +01003218 int fchmodat_unsupported = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003219#endif
3220
Larry Hastings9cf065c2012-06-22 16:30:09 -07003221#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3222 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003223 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003224#endif
3225
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003226 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3227 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3228 return NULL;
3229 }
3230
Larry Hastings9cf065c2012-06-22 16:30:09 -07003231#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003233 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003234 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235 result = 0;
3236 else {
3237 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003238 attr &= ~FILE_ATTRIBUTE_READONLY;
3239 else
3240 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003241 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003242 }
3243 Py_END_ALLOW_THREADS
3244
3245 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003246 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003247 }
3248#else /* MS_WINDOWS */
3249 Py_BEGIN_ALLOW_THREADS
3250#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003251 if (path->fd != -1)
3252 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003253 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003254#endif /* HAVE_CHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003255#ifdef HAVE_LCHMOD
3256 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003257 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003258 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003259#endif /* HAVE_LCHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003260#ifdef HAVE_FCHMODAT
3261 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
Ronald Oussoren41761932020-11-08 10:05:27 +01003262 if (HAVE_FCHMODAT_RUNTIME) {
3263 /*
3264 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3265 * The documentation specifically shows how to use it,
3266 * and then says it isn't implemented yet.
3267 * (true on linux with glibc 2.15, and openindiana 3.x)
3268 *
3269 * Once it is supported, os.chmod will automatically
3270 * support dir_fd and follow_symlinks=False. (Hopefully.)
3271 * Until then, we need to be careful what exception we raise.
3272 */
3273 result = fchmodat(dir_fd, path->narrow, mode,
3274 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3275 /*
3276 * But wait! We can't throw the exception without allowing threads,
3277 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3278 */
3279 fchmodat_nofollow_unsupported =
3280 result &&
3281 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3282 !follow_symlinks;
3283 } else {
3284 fchmodat_unsupported = 1;
3285 fchmodat_nofollow_unsupported = 1;
3286
3287 result = -1;
3288 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 }
3290 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003291#endif /* HAVE_FHCMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003292 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003293 Py_END_ALLOW_THREADS
3294
3295 if (result) {
3296#ifdef HAVE_FCHMODAT
Ronald Oussoren41761932020-11-08 10:05:27 +01003297 if (fchmodat_unsupported) {
3298 if (dir_fd != DEFAULT_DIR_FD) {
3299 argument_unavailable_error("chmod", "dir_fd");
3300 return NULL;
3301 }
3302 }
3303
Larry Hastings9cf065c2012-06-22 16:30:09 -07003304 if (fchmodat_nofollow_unsupported) {
3305 if (dir_fd != DEFAULT_DIR_FD)
3306 dir_fd_and_follow_symlinks_invalid("chmod",
3307 dir_fd, follow_symlinks);
3308 else
3309 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003310 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003311 }
3312 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003313#endif /* HAVE_FCHMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003314 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003315 }
Ronald Oussoren41761932020-11-08 10:05:27 +01003316#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003317
Larry Hastings2f936352014-08-05 14:04:04 +10003318 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003319}
3320
Larry Hastings9cf065c2012-06-22 16:30:09 -07003321
Christian Heimes4e30a842007-11-30 22:12:06 +00003322#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003323/*[clinic input]
3324os.fchmod
3325
3326 fd: int
3327 mode: int
3328
3329Change the access permissions of the file given by file descriptor fd.
3330
3331Equivalent to os.chmod(fd, mode).
3332[clinic start generated code]*/
3333
Larry Hastings2f936352014-08-05 14:04:04 +10003334static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003335os_fchmod_impl(PyObject *module, int fd, int mode)
3336/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003337{
3338 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003339 int async_err = 0;
3340
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003341 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3342 return NULL;
3343 }
3344
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003345 do {
3346 Py_BEGIN_ALLOW_THREADS
3347 res = fchmod(fd, mode);
3348 Py_END_ALLOW_THREADS
3349 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3350 if (res != 0)
3351 return (!async_err) ? posix_error() : NULL;
3352
Victor Stinner8c62be82010-05-06 00:08:46 +00003353 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003354}
3355#endif /* HAVE_FCHMOD */
3356
Larry Hastings2f936352014-08-05 14:04:04 +10003357
Christian Heimes4e30a842007-11-30 22:12:06 +00003358#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003359/*[clinic input]
3360os.lchmod
3361
3362 path: path_t
3363 mode: int
3364
3365Change the access permissions of a file, without following symbolic links.
3366
3367If path is a symlink, this affects the link itself rather than the target.
3368Equivalent to chmod(path, mode, follow_symlinks=False)."
3369[clinic start generated code]*/
3370
Larry Hastings2f936352014-08-05 14:04:04 +10003371static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003372os_lchmod_impl(PyObject *module, path_t *path, int mode)
3373/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003374{
Victor Stinner8c62be82010-05-06 00:08:46 +00003375 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003376 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3377 return NULL;
3378 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003379 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003380 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003381 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003382 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003383 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003384 return NULL;
3385 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003386 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003387}
3388#endif /* HAVE_LCHMOD */
3389
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003390
Thomas Wouterscf297e42007-02-23 15:07:44 +00003391#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003392/*[clinic input]
3393os.chflags
3394
3395 path: path_t
3396 flags: unsigned_long(bitwise=True)
3397 follow_symlinks: bool=True
3398
3399Set file flags.
3400
3401If follow_symlinks is False, and the last element of the path is a symbolic
3402 link, chflags will change flags on the symbolic link itself instead of the
3403 file the link points to.
3404follow_symlinks may not be implemented on your platform. If it is
3405unavailable, using it will raise a NotImplementedError.
3406
3407[clinic start generated code]*/
3408
Larry Hastings2f936352014-08-05 14:04:04 +10003409static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003410os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003411 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003412/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003413{
3414 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003415
3416#ifndef HAVE_LCHFLAGS
3417 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003418 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003419#endif
3420
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003421 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3422 return NULL;
3423 }
3424
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426#ifdef HAVE_LCHFLAGS
3427 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003428 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003429 else
3430#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003431 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003433
Larry Hastings2f936352014-08-05 14:04:04 +10003434 if (result)
3435 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003436
Larry Hastings2f936352014-08-05 14:04:04 +10003437 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003438}
3439#endif /* HAVE_CHFLAGS */
3440
Larry Hastings2f936352014-08-05 14:04:04 +10003441
Thomas Wouterscf297e42007-02-23 15:07:44 +00003442#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003443/*[clinic input]
3444os.lchflags
3445
3446 path: path_t
3447 flags: unsigned_long(bitwise=True)
3448
3449Set file flags.
3450
3451This function will not follow symbolic links.
3452Equivalent to chflags(path, flags, follow_symlinks=False).
3453[clinic start generated code]*/
3454
Larry Hastings2f936352014-08-05 14:04:04 +10003455static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003456os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3457/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003458{
Victor Stinner8c62be82010-05-06 00:08:46 +00003459 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003460 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3461 return NULL;
3462 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003464 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003465 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003466 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003467 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003468 }
Victor Stinner292c8352012-10-30 02:17:38 +01003469 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003470}
3471#endif /* HAVE_LCHFLAGS */
3472
Larry Hastings2f936352014-08-05 14:04:04 +10003473
Martin v. Löwis244edc82001-10-04 22:44:26 +00003474#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003475/*[clinic input]
3476os.chroot
3477 path: path_t
3478
3479Change root directory to path.
3480
3481[clinic start generated code]*/
3482
Larry Hastings2f936352014-08-05 14:04:04 +10003483static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003484os_chroot_impl(PyObject *module, path_t *path)
3485/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003486{
3487 int res;
3488 Py_BEGIN_ALLOW_THREADS
3489 res = chroot(path->narrow);
3490 Py_END_ALLOW_THREADS
3491 if (res < 0)
3492 return path_error(path);
3493 Py_RETURN_NONE;
3494}
3495#endif /* HAVE_CHROOT */
3496
Martin v. Löwis244edc82001-10-04 22:44:26 +00003497
Guido van Rossum21142a01999-01-08 21:05:37 +00003498#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003499/*[clinic input]
3500os.fsync
3501
3502 fd: fildes
3503
3504Force write of fd to disk.
3505[clinic start generated code]*/
3506
Larry Hastings2f936352014-08-05 14:04:04 +10003507static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003508os_fsync_impl(PyObject *module, int fd)
3509/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003510{
3511 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003512}
3513#endif /* HAVE_FSYNC */
3514
Larry Hastings2f936352014-08-05 14:04:04 +10003515
Ross Lagerwall7807c352011-03-17 20:20:30 +02003516#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003517/*[clinic input]
3518os.sync
3519
3520Force write of everything to disk.
3521[clinic start generated code]*/
3522
Larry Hastings2f936352014-08-05 14:04:04 +10003523static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003524os_sync_impl(PyObject *module)
3525/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003526{
3527 Py_BEGIN_ALLOW_THREADS
3528 sync();
3529 Py_END_ALLOW_THREADS
3530 Py_RETURN_NONE;
3531}
Larry Hastings2f936352014-08-05 14:04:04 +10003532#endif /* HAVE_SYNC */
3533
Ross Lagerwall7807c352011-03-17 20:20:30 +02003534
Guido van Rossum21142a01999-01-08 21:05:37 +00003535#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003536#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003537extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3538#endif
3539
Larry Hastings2f936352014-08-05 14:04:04 +10003540/*[clinic input]
3541os.fdatasync
3542
3543 fd: fildes
3544
3545Force write of fd to disk without forcing update of metadata.
3546[clinic start generated code]*/
3547
Larry Hastings2f936352014-08-05 14:04:04 +10003548static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003549os_fdatasync_impl(PyObject *module, int fd)
3550/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003551{
3552 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003553}
3554#endif /* HAVE_FDATASYNC */
3555
3556
Fredrik Lundh10723342000-07-10 16:38:09 +00003557#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003558/*[clinic input]
3559os.chown
3560
3561 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003562 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003563
3564 uid: uid_t
3565
3566 gid: gid_t
3567
3568 *
3569
3570 dir_fd : dir_fd(requires='fchownat') = None
3571 If not None, it should be a file descriptor open to a directory,
3572 and path should be relative; path will then be relative to that
3573 directory.
3574
3575 follow_symlinks: bool = True
3576 If False, and the last element of the path is a symbolic link,
3577 stat will examine the symbolic link itself instead of the file
3578 the link points to.
3579
3580Change the owner and group id of path to the numeric uid and gid.\
3581
3582path may always be specified as a string.
3583On some platforms, path may also be specified as an open file descriptor.
3584 If this functionality is unavailable, using it raises an exception.
3585If dir_fd is not None, it should be a file descriptor open to a directory,
3586 and path should be relative; path will then be relative to that directory.
3587If follow_symlinks is False, and the last element of the path is a symbolic
3588 link, chown will modify the symbolic link itself instead of the file the
3589 link points to.
3590It is an error to use dir_fd or follow_symlinks when specifying path as
3591 an open file descriptor.
3592dir_fd and follow_symlinks may not be implemented on your platform.
3593 If they are unavailable, using them will raise a NotImplementedError.
3594
3595[clinic start generated code]*/
3596
Larry Hastings2f936352014-08-05 14:04:04 +10003597static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003598os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003599 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003600/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003601{
3602 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003603
Ronald Oussoren41761932020-11-08 10:05:27 +01003604#if defined(HAVE_FCHOWNAT)
3605 int fchownat_unsupported = 0;
3606#endif
3607
Larry Hastings9cf065c2012-06-22 16:30:09 -07003608#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3609 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003610 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003612 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3613 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3614 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003616 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3617 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3618 return NULL;
3619 }
3620
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003622#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003623 if (path->fd != -1)
3624 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 else
3626#endif
3627#ifdef HAVE_LCHOWN
3628 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003629 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003630 else
3631#endif
3632#ifdef HAVE_FCHOWNAT
Ronald Oussoren41761932020-11-08 10:05:27 +01003633 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
3634 if (HAVE_FCHOWNAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10003635 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +01003637 } else {
3638 fchownat_unsupported = 1;
3639 }
3640 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003641#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003642 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644
Ronald Oussoren41761932020-11-08 10:05:27 +01003645#ifdef HAVE_FCHOWNAT
3646 if (fchownat_unsupported) {
3647 /* This would be incorrect if the current platform
3648 * doesn't support lchown.
3649 */
3650 argument_unavailable_error(NULL, "dir_fd");
3651 return NULL;
3652 }
3653#endif
3654
Larry Hastings2f936352014-08-05 14:04:04 +10003655 if (result)
3656 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003657
Larry Hastings2f936352014-08-05 14:04:04 +10003658 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003659}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003660#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003661
Larry Hastings2f936352014-08-05 14:04:04 +10003662
Christian Heimes4e30a842007-11-30 22:12:06 +00003663#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003664/*[clinic input]
3665os.fchown
3666
3667 fd: int
3668 uid: uid_t
3669 gid: gid_t
3670
3671Change the owner and group id of the file specified by file descriptor.
3672
3673Equivalent to os.chown(fd, uid, gid).
3674
3675[clinic start generated code]*/
3676
Larry Hastings2f936352014-08-05 14:04:04 +10003677static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003678os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3679/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003680{
Victor Stinner8c62be82010-05-06 00:08:46 +00003681 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003682 int async_err = 0;
3683
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003684 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3685 return NULL;
3686 }
3687
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003688 do {
3689 Py_BEGIN_ALLOW_THREADS
3690 res = fchown(fd, uid, gid);
3691 Py_END_ALLOW_THREADS
3692 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3693 if (res != 0)
3694 return (!async_err) ? posix_error() : NULL;
3695
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003697}
3698#endif /* HAVE_FCHOWN */
3699
Larry Hastings2f936352014-08-05 14:04:04 +10003700
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003701#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003702/*[clinic input]
3703os.lchown
3704
3705 path : path_t
3706 uid: uid_t
3707 gid: gid_t
3708
3709Change the owner and group id of path to the numeric uid and gid.
3710
3711This function will not follow symbolic links.
3712Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3713[clinic start generated code]*/
3714
Larry Hastings2f936352014-08-05 14:04:04 +10003715static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003716os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3717/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003718{
Victor Stinner8c62be82010-05-06 00:08:46 +00003719 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003720 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3721 return NULL;
3722 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003723 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003724 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003725 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003726 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003727 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003728 }
Larry Hastings2f936352014-08-05 14:04:04 +10003729 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003730}
3731#endif /* HAVE_LCHOWN */
3732
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003733
Barry Warsaw53699e91996-12-10 23:23:01 +00003734static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003735posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003736{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003737#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003738 wchar_t wbuf[MAXPATHLEN];
3739 wchar_t *wbuf2 = wbuf;
3740 DWORD len;
3741
3742 Py_BEGIN_ALLOW_THREADS
3743 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3744 /* If the buffer is large enough, len does not include the
3745 terminating \0. If the buffer is too small, len includes
3746 the space needed for the terminator. */
3747 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003748 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003749 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003750 }
Victor Stinner689830e2019-06-26 17:31:12 +02003751 else {
3752 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003753 }
Victor Stinner689830e2019-06-26 17:31:12 +02003754 if (wbuf2) {
3755 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003756 }
Victor Stinner689830e2019-06-26 17:31:12 +02003757 }
3758 Py_END_ALLOW_THREADS
3759
3760 if (!wbuf2) {
3761 PyErr_NoMemory();
3762 return NULL;
3763 }
3764 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003765 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003766 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003767 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003768 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003769
Victor Stinner689830e2019-06-26 17:31:12 +02003770 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3771 if (wbuf2 != wbuf) {
3772 PyMem_RawFree(wbuf2);
3773 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003774
Victor Stinner689830e2019-06-26 17:31:12 +02003775 if (use_bytes) {
3776 if (resobj == NULL) {
3777 return NULL;
3778 }
3779 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3780 }
3781
3782 return resobj;
3783#else
3784 const size_t chunk = 1024;
3785
3786 char *buf = NULL;
3787 char *cwd = NULL;
3788 size_t buflen = 0;
3789
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003791 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003792 char *newbuf;
3793 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3794 buflen += chunk;
3795 newbuf = PyMem_RawRealloc(buf, buflen);
3796 }
3797 else {
3798 newbuf = NULL;
3799 }
3800 if (newbuf == NULL) {
3801 PyMem_RawFree(buf);
3802 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003803 break;
3804 }
Victor Stinner689830e2019-06-26 17:31:12 +02003805 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003806
Victor Stinner4403d7d2015-04-25 00:16:10 +02003807 cwd = getcwd(buf, buflen);
3808 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003809 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003810
Victor Stinner689830e2019-06-26 17:31:12 +02003811 if (buf == NULL) {
3812 return PyErr_NoMemory();
3813 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003814 if (cwd == NULL) {
3815 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003816 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003817 }
3818
Victor Stinner689830e2019-06-26 17:31:12 +02003819 PyObject *obj;
3820 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003821 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003822 }
3823 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003824 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003825 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003826 PyMem_RawFree(buf);
3827
3828 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003829#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003830}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003831
Larry Hastings2f936352014-08-05 14:04:04 +10003832
3833/*[clinic input]
3834os.getcwd
3835
3836Return a unicode string representing the current working directory.
3837[clinic start generated code]*/
3838
Larry Hastings2f936352014-08-05 14:04:04 +10003839static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003840os_getcwd_impl(PyObject *module)
3841/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003842{
3843 return posix_getcwd(0);
3844}
3845
Larry Hastings2f936352014-08-05 14:04:04 +10003846
3847/*[clinic input]
3848os.getcwdb
3849
3850Return a bytes string representing the current working directory.
3851[clinic start generated code]*/
3852
Larry Hastings2f936352014-08-05 14:04:04 +10003853static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003854os_getcwdb_impl(PyObject *module)
3855/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003856{
3857 return posix_getcwd(1);
3858}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003859
Larry Hastings2f936352014-08-05 14:04:04 +10003860
Larry Hastings9cf065c2012-06-22 16:30:09 -07003861#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3862#define HAVE_LINK 1
3863#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003864
Guido van Rossumb6775db1994-08-01 11:34:53 +00003865#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003866/*[clinic input]
3867
3868os.link
3869
3870 src : path_t
3871 dst : path_t
3872 *
3873 src_dir_fd : dir_fd = None
3874 dst_dir_fd : dir_fd = None
3875 follow_symlinks: bool = True
3876
3877Create a hard link to a file.
3878
3879If either src_dir_fd or dst_dir_fd is not None, it should be a file
3880 descriptor open to a directory, and the respective path string (src or dst)
3881 should be relative; the path will then be relative to that directory.
3882If follow_symlinks is False, and the last element of src is a symbolic
3883 link, link will create a link to the symbolic link itself instead of the
3884 file the link points to.
3885src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3886 platform. If they are unavailable, using them will raise a
3887 NotImplementedError.
3888[clinic start generated code]*/
3889
Larry Hastings2f936352014-08-05 14:04:04 +10003890static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003891os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003892 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003893/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003894{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003895#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003896 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003897#else
3898 int result;
3899#endif
Ronald Oussoren41761932020-11-08 10:05:27 +01003900#if defined(HAVE_LINKAT)
3901 int linkat_unavailable = 0;
3902#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003903
Larry Hastings9cf065c2012-06-22 16:30:09 -07003904#ifndef HAVE_LINKAT
3905 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3906 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003907 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003908 }
3909#endif
3910
Steve Dowercc16be82016-09-08 10:35:16 -07003911#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003912 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003913 PyErr_SetString(PyExc_NotImplementedError,
3914 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003915 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003916 }
Steve Dowercc16be82016-09-08 10:35:16 -07003917#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003918
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003919 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3920 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3921 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3922 return NULL;
3923 }
3924
Brian Curtin1b9df392010-11-24 20:24:31 +00003925#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003926 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003927 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003928 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003929
Larry Hastings2f936352014-08-05 14:04:04 +10003930 if (!result)
3931 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003932#else
3933 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003934#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003935 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3936 (dst_dir_fd != DEFAULT_DIR_FD) ||
Ronald Oussoren41761932020-11-08 10:05:27 +01003937 (!follow_symlinks)) {
3938
3939 if (HAVE_LINKAT_RUNTIME) {
3940
3941 result = linkat(src_dir_fd, src->narrow,
3942 dst_dir_fd, dst->narrow,
3943 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3944
3945 }
3946#ifdef __APPLE__
3947 else {
3948 if (src_dir_fd == DEFAULT_DIR_FD && dst_dir_fd == DEFAULT_DIR_FD) {
3949 /* See issue 41355: This matches the behaviour of !HAVE_LINKAT */
3950 result = link(src->narrow, dst->narrow);
3951 } else {
3952 linkat_unavailable = 1;
3953 }
3954 }
3955#endif
3956 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003957 else
Steve Dowercc16be82016-09-08 10:35:16 -07003958#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003959 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003960 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003961
Ronald Oussoren41761932020-11-08 10:05:27 +01003962#ifdef HAVE_LINKAT
3963 if (linkat_unavailable) {
3964 /* Either or both dir_fd arguments were specified */
3965 if (src_dir_fd != DEFAULT_DIR_FD) {
3966 argument_unavailable_error("link", "src_dir_fd");
3967 } else {
3968 argument_unavailable_error("link", "dst_dir_fd");
3969 }
3970 return NULL;
3971 }
3972#endif
3973
Larry Hastings2f936352014-08-05 14:04:04 +10003974 if (result)
3975 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003976#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003977
Larry Hastings2f936352014-08-05 14:04:04 +10003978 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003979}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003980#endif
3981
Brian Curtin1b9df392010-11-24 20:24:31 +00003982
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003983#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003984static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003985_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003986{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003987 PyObject *v;
3988 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3989 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003990 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003991 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003992 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003993 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003994
Steve Dowercc16be82016-09-08 10:35:16 -07003995 WIN32_FIND_DATAW wFileData;
3996 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003997
Steve Dowercc16be82016-09-08 10:35:16 -07003998 if (!path->wide) { /* Default arg: "." */
3999 po_wchars = L".";
4000 len = 1;
4001 } else {
4002 po_wchars = path->wide;
4003 len = wcslen(path->wide);
4004 }
4005 /* The +5 is so we can append "\\*.*\0" */
4006 wnamebuf = PyMem_New(wchar_t, len + 5);
4007 if (!wnamebuf) {
4008 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07004009 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004010 }
Steve Dowercc16be82016-09-08 10:35:16 -07004011 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00004012 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07004013 wchar_t wch = wnamebuf[len-1];
4014 if (wch != SEP && wch != ALTSEP && wch != L':')
4015 wnamebuf[len++] = SEP;
4016 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00004017 }
Steve Dowercc16be82016-09-08 10:35:16 -07004018 if ((list = PyList_New(0)) == NULL) {
4019 goto exit;
4020 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00004021 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004022 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00004023 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004024 if (hFindFile == INVALID_HANDLE_VALUE) {
4025 int error = GetLastError();
4026 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004027 goto exit;
4028 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004029 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004030 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004031 }
4032 do {
4033 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07004034 if (wcscmp(wFileData.cFileName, L".") != 0 &&
4035 wcscmp(wFileData.cFileName, L"..") != 0) {
4036 v = PyUnicode_FromWideChar(wFileData.cFileName,
4037 wcslen(wFileData.cFileName));
4038 if (path->narrow && v) {
4039 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
4040 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004041 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004042 Py_DECREF(list);
4043 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004044 break;
4045 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004046 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004047 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004048 Py_DECREF(list);
4049 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004050 break;
4051 }
4052 Py_DECREF(v);
4053 }
4054 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004055 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00004056 Py_END_ALLOW_THREADS
4057 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4058 it got to the end of the directory. */
4059 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004060 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004061 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004062 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004063 }
4064 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004065
Larry Hastings9cf065c2012-06-22 16:30:09 -07004066exit:
4067 if (hFindFile != INVALID_HANDLE_VALUE) {
4068 if (FindClose(hFindFile) == FALSE) {
4069 if (list != NULL) {
4070 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004071 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004072 }
4073 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004074 }
Victor Stinnerb6404912013-07-07 16:21:41 +02004075 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004076
Larry Hastings9cf065c2012-06-22 16:30:09 -07004077 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004078} /* end of _listdir_windows_no_opendir */
4079
4080#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
4081
4082static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004083_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004084{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004085 PyObject *v;
4086 DIR *dirp = NULL;
4087 struct dirent *ep;
4088 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004089#ifdef HAVE_FDOPENDIR
4090 int fd = -1;
4091#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004092
Victor Stinner8c62be82010-05-06 00:08:46 +00004093 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004094#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07004095 if (path->fd != -1) {
Ronald Oussoren41761932020-11-08 10:05:27 +01004096 if (HAVE_FDOPENDIR_RUNTIME) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004097 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02004098 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01004099 if (fd == -1)
4100 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004101
Larry Hastingsfdaea062012-06-25 04:42:23 -07004102 return_str = 1;
4103
Larry Hastings9cf065c2012-06-22 16:30:09 -07004104 Py_BEGIN_ALLOW_THREADS
4105 dirp = fdopendir(fd);
4106 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01004107 } else {
4108 PyErr_SetString(PyExc_TypeError,
4109 "listdir: path should be string, bytes, os.PathLike or None, not int");
4110 return NULL;
4111 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004112 }
4113 else
4114#endif
4115 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004116 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07004117 if (path->narrow) {
4118 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03004119 /* only return bytes if they specified a bytes-like object */
4120 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07004121 }
4122 else {
4123 name = ".";
4124 return_str = 1;
4125 }
4126
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127 Py_BEGIN_ALLOW_THREADS
4128 dirp = opendir(name);
4129 Py_END_ALLOW_THREADS
4130 }
4131
4132 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07004133 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004134#ifdef HAVE_FDOPENDIR
4135 if (fd != -1) {
4136 Py_BEGIN_ALLOW_THREADS
4137 close(fd);
4138 Py_END_ALLOW_THREADS
4139 }
4140#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004141 goto exit;
4142 }
4143 if ((list = PyList_New(0)) == NULL) {
4144 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004145 }
4146 for (;;) {
4147 errno = 0;
4148 Py_BEGIN_ALLOW_THREADS
4149 ep = readdir(dirp);
4150 Py_END_ALLOW_THREADS
4151 if (ep == NULL) {
4152 if (errno == 0) {
4153 break;
4154 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004156 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004157 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004158 }
4159 }
4160 if (ep->d_name[0] == '.' &&
4161 (NAMLEN(ep) == 1 ||
4162 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
4163 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07004164 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00004165 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
4166 else
4167 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00004168 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004169 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 break;
4171 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004172 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004173 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004174 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004175 break;
4176 }
4177 Py_DECREF(v);
4178 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00004179
Larry Hastings9cf065c2012-06-22 16:30:09 -07004180exit:
4181 if (dirp != NULL) {
4182 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004183#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07004184 if (fd > -1)
4185 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004186#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004187 closedir(dirp);
4188 Py_END_ALLOW_THREADS
4189 }
4190
Larry Hastings9cf065c2012-06-22 16:30:09 -07004191 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004192} /* end of _posix_listdir */
4193#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004194
Larry Hastings2f936352014-08-05 14:04:04 +10004195
4196/*[clinic input]
4197os.listdir
4198
4199 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
4200
4201Return a list containing the names of the files in the directory.
4202
BNMetricsb9427072018-11-02 15:20:19 +00004203path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10004204 the filenames returned will also be bytes; in all other circumstances
4205 the filenames returned will be str.
4206If path is None, uses the path='.'.
4207On some platforms, path may also be specified as an open file descriptor;\
4208 the file descriptor must refer to a directory.
4209 If this functionality is unavailable, using it raises NotImplementedError.
4210
4211The list is in arbitrary order. It does not include the special
4212entries '.' and '..' even if they are present in the directory.
4213
4214
4215[clinic start generated code]*/
4216
Larry Hastings2f936352014-08-05 14:04:04 +10004217static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004218os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00004219/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004220{
Steve Dower60419a72019-06-24 08:42:54 -07004221 if (PySys_Audit("os.listdir", "O",
4222 path->object ? path->object : Py_None) < 0) {
4223 return NULL;
4224 }
Larry Hastings2f936352014-08-05 14:04:04 +10004225#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4226 return _listdir_windows_no_opendir(path, NULL);
4227#else
4228 return _posix_listdir(path, NULL);
4229#endif
4230}
4231
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004232#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00004233/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004234/*[clinic input]
4235os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02004236
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004237 path: path_t
4238 /
4239
4240[clinic start generated code]*/
4241
4242static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004243os__getfullpathname_impl(PyObject *module, path_t *path)
4244/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004245{
Victor Stinner3939c322019-06-25 15:02:43 +02004246 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004247
Victor Stinner3939c322019-06-25 15:02:43 +02004248 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
4249 if (_Py_abspath(path->wide, &abspath) < 0) {
4250 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00004251 }
Victor Stinner3939c322019-06-25 15:02:43 +02004252 if (abspath == NULL) {
4253 return PyErr_NoMemory();
4254 }
4255
4256 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
4257 PyMem_RawFree(abspath);
4258 if (str == NULL) {
4259 return NULL;
4260 }
4261 if (path->narrow) {
4262 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
4263 }
4264 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10004265}
Brian Curtind40e6f72010-07-08 21:39:08 +00004266
Brian Curtind25aef52011-06-13 15:16:04 -05004267
Larry Hastings2f936352014-08-05 14:04:04 +10004268/*[clinic input]
4269os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004270
Steve Dower23ad6d02018-02-22 10:39:10 -08004271 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004272 /
4273
4274A helper function for samepath on windows.
4275[clinic start generated code]*/
4276
Larry Hastings2f936352014-08-05 14:04:04 +10004277static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004278os__getfinalpathname_impl(PyObject *module, path_t *path)
4279/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004280{
4281 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004282 wchar_t buf[MAXPATHLEN], *target_path = buf;
4283 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004284 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004285 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004286
Steve Dower23ad6d02018-02-22 10:39:10 -08004287 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004288 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004289 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004290 0, /* desired access */
4291 0, /* share mode */
4292 NULL, /* security attributes */
4293 OPEN_EXISTING,
4294 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4295 FILE_FLAG_BACKUP_SEMANTICS,
4296 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004297 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004298
Steve Dower23ad6d02018-02-22 10:39:10 -08004299 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004300 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004301 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004302
4303 /* We have a good handle to the target, use it to determine the
4304 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004305 while (1) {
4306 Py_BEGIN_ALLOW_THREADS
4307 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4308 buf_size, VOLUME_NAME_DOS);
4309 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004310
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004311 if (!result_length) {
4312 result = win32_error_object("GetFinalPathNameByHandleW",
4313 path->object);
4314 goto cleanup;
4315 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004316
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004317 if (result_length < buf_size) {
4318 break;
4319 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004320
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004321 wchar_t *tmp;
4322 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4323 result_length * sizeof(*tmp));
4324 if (!tmp) {
4325 result = PyErr_NoMemory();
4326 goto cleanup;
4327 }
4328
4329 buf_size = result_length;
4330 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004331 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004332
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004333 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004334 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004335 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004336 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004337
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004338cleanup:
4339 if (target_path != buf) {
4340 PyMem_Free(target_path);
4341 }
4342 CloseHandle(hFile);
4343 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004344}
Brian Curtin62857742010-09-06 17:07:27 +00004345
Tim Golden6b528062013-08-01 12:44:00 +01004346
Larry Hastings2f936352014-08-05 14:04:04 +10004347/*[clinic input]
4348os._getvolumepathname
4349
Steve Dower23ad6d02018-02-22 10:39:10 -08004350 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004351
4352A helper function for ismount on Win32.
4353[clinic start generated code]*/
4354
Larry Hastings2f936352014-08-05 14:04:04 +10004355static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004356os__getvolumepathname_impl(PyObject *module, path_t *path)
4357/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004358{
4359 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004360 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004361 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004362 BOOL ret;
4363
Tim Golden6b528062013-08-01 12:44:00 +01004364 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004365 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004366
Victor Stinner850a18e2017-10-24 16:53:32 -07004367 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004368 PyErr_SetString(PyExc_OverflowError, "path too long");
4369 return NULL;
4370 }
4371
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004372 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004373 if (mountpath == NULL)
4374 return PyErr_NoMemory();
4375
4376 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004377 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004378 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004379 Py_END_ALLOW_THREADS
4380
4381 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004382 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004383 goto exit;
4384 }
4385 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004386 if (path->narrow)
4387 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004388
4389exit:
4390 PyMem_Free(mountpath);
4391 return result;
4392}
Tim Golden6b528062013-08-01 12:44:00 +01004393
Steve Dower04732ca2021-04-07 01:02:07 +01004394
4395/*[clinic input]
4396os._path_splitroot
4397
4398 path: path_t
4399
4400Removes everything after the root on Win32.
4401[clinic start generated code]*/
4402
4403static PyObject *
4404os__path_splitroot_impl(PyObject *module, path_t *path)
4405/*[clinic end generated code: output=ab7f1a88b654581c input=dc93b1d3984cffb6]*/
4406{
4407 wchar_t *buffer;
4408 wchar_t *end;
4409 PyObject *result = NULL;
4410 HRESULT ret;
4411
4412 buffer = (wchar_t*)PyMem_Malloc(sizeof(wchar_t) * (wcslen(path->wide) + 1));
4413 if (!buffer) {
4414 return NULL;
4415 }
4416 wcscpy(buffer, path->wide);
4417 for (wchar_t *p = wcschr(buffer, L'/'); p; p = wcschr(p, L'/')) {
4418 *p = L'\\';
4419 }
4420
4421 Py_BEGIN_ALLOW_THREADS
4422 ret = PathCchSkipRoot(buffer, &end);
4423 Py_END_ALLOW_THREADS
4424 if (FAILED(ret)) {
4425 result = Py_BuildValue("sO", "", path->object);
4426 } else if (end != buffer) {
4427 size_t rootLen = (size_t)(end - buffer);
4428 result = Py_BuildValue("NN",
4429 PyUnicode_FromWideChar(path->wide, rootLen),
4430 PyUnicode_FromWideChar(path->wide + rootLen, -1)
4431 );
4432 } else {
4433 result = Py_BuildValue("Os", path->object, "");
4434 }
4435 PyMem_Free(buffer);
4436
4437 return result;
4438}
4439
4440
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004441#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004442
Larry Hastings2f936352014-08-05 14:04:04 +10004443
4444/*[clinic input]
4445os.mkdir
4446
4447 path : path_t
4448
4449 mode: int = 0o777
4450
4451 *
4452
4453 dir_fd : dir_fd(requires='mkdirat') = None
4454
4455# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4456
4457Create a directory.
4458
4459If dir_fd is not None, it should be a file descriptor open to a directory,
4460 and path should be relative; path will then be relative to that directory.
4461dir_fd may not be implemented on your platform.
4462 If it is unavailable, using it will raise a NotImplementedError.
4463
4464The mode argument is ignored on Windows.
4465[clinic start generated code]*/
4466
Larry Hastings2f936352014-08-05 14:04:04 +10004467static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004468os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4469/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004470{
4471 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004472#ifdef HAVE_MKDIRAT
4473 int mkdirat_unavailable = 0;
4474#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004475
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004476 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4477 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4478 return NULL;
4479 }
4480
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004481#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004482 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004483 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004484 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004485
Larry Hastings2f936352014-08-05 14:04:04 +10004486 if (!result)
4487 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004488#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004489 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004490#if HAVE_MKDIRAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004491 if (dir_fd != DEFAULT_DIR_FD) {
4492 if (HAVE_MKDIRAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004493 result = mkdirat(dir_fd, path->narrow, mode);
Ronald Oussoren41761932020-11-08 10:05:27 +01004494
4495 } else {
4496 mkdirat_unavailable = 1;
4497 }
4498 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004499#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004500#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004501 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004502#else
Larry Hastings2f936352014-08-05 14:04:04 +10004503 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004504#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004505 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01004506
4507#if HAVE_MKDIRAT
4508 if (mkdirat_unavailable) {
4509 argument_unavailable_error(NULL, "dir_fd");
4510 return NULL;
4511 }
4512#endif
4513
Larry Hastings2f936352014-08-05 14:04:04 +10004514 if (result < 0)
4515 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004516#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004517 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004518}
4519
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004520
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004521/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4522#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004523#include <sys/resource.h>
4524#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004525
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004526
4527#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004528/*[clinic input]
4529os.nice
4530
4531 increment: int
4532 /
4533
4534Add increment to the priority of process and return the new priority.
4535[clinic start generated code]*/
4536
Larry Hastings2f936352014-08-05 14:04:04 +10004537static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004538os_nice_impl(PyObject *module, int increment)
4539/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004540{
4541 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004542
Victor Stinner8c62be82010-05-06 00:08:46 +00004543 /* There are two flavours of 'nice': one that returns the new
4544 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004545 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004546 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004547
Victor Stinner8c62be82010-05-06 00:08:46 +00004548 If we are of the nice family that returns the new priority, we
4549 need to clear errno before the call, and check if errno is filled
4550 before calling posix_error() on a returnvalue of -1, because the
4551 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004552
Victor Stinner8c62be82010-05-06 00:08:46 +00004553 errno = 0;
4554 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004555#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004556 if (value == 0)
4557 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004558#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004559 if (value == -1 && errno != 0)
4560 /* either nice() or getpriority() returned an error */
4561 return posix_error();
4562 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004563}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004564#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004565
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004566
4567#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004568/*[clinic input]
4569os.getpriority
4570
4571 which: int
4572 who: int
4573
4574Return program scheduling priority.
4575[clinic start generated code]*/
4576
Larry Hastings2f936352014-08-05 14:04:04 +10004577static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004578os_getpriority_impl(PyObject *module, int which, int who)
4579/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004580{
4581 int retval;
4582
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004583 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004584 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004585 if (errno != 0)
4586 return posix_error();
4587 return PyLong_FromLong((long)retval);
4588}
4589#endif /* HAVE_GETPRIORITY */
4590
4591
4592#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004593/*[clinic input]
4594os.setpriority
4595
4596 which: int
4597 who: int
4598 priority: int
4599
4600Set program scheduling priority.
4601[clinic start generated code]*/
4602
Larry Hastings2f936352014-08-05 14:04:04 +10004603static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004604os_setpriority_impl(PyObject *module, int which, int who, int priority)
4605/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004606{
4607 int retval;
4608
4609 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004610 if (retval == -1)
4611 return posix_error();
4612 Py_RETURN_NONE;
4613}
4614#endif /* HAVE_SETPRIORITY */
4615
4616
Barry Warsaw53699e91996-12-10 23:23:01 +00004617static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004618internal_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 +00004619{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004620 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004621 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004622
Ronald Oussoren41761932020-11-08 10:05:27 +01004623#ifdef HAVE_RENAMEAT
4624 int renameat_unavailable = 0;
4625#endif
4626
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004627#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004628 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004629 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004630#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004632#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004633
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4635 (dst_dir_fd != DEFAULT_DIR_FD);
4636#ifndef HAVE_RENAMEAT
4637 if (dir_fd_specified) {
4638 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004639 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004640 }
4641#endif
4642
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004643 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4644 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4645 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4646 return NULL;
4647 }
4648
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649#ifdef MS_WINDOWS
4650 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004651 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652 Py_END_ALLOW_THREADS
4653
Larry Hastings2f936352014-08-05 14:04:04 +10004654 if (!result)
4655 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004656
4657#else
Steve Dowercc16be82016-09-08 10:35:16 -07004658 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4659 PyErr_Format(PyExc_ValueError,
4660 "%s: src and dst must be the same type", function_name);
4661 return NULL;
4662 }
4663
Larry Hastings9cf065c2012-06-22 16:30:09 -07004664 Py_BEGIN_ALLOW_THREADS
4665#ifdef HAVE_RENAMEAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004666 if (dir_fd_specified) {
4667 if (HAVE_RENAMEAT_RUNTIME) {
4668 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
4669 } else {
4670 renameat_unavailable = 1;
4671 }
4672 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004673#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004674 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675 Py_END_ALLOW_THREADS
4676
Ronald Oussoren41761932020-11-08 10:05:27 +01004677
4678#ifdef HAVE_RENAMEAT
4679 if (renameat_unavailable) {
4680 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4681 return NULL;
4682 }
4683#endif
4684
Larry Hastings2f936352014-08-05 14:04:04 +10004685 if (result)
4686 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004687#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004688 Py_RETURN_NONE;
4689}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690
Larry Hastings2f936352014-08-05 14:04:04 +10004691
4692/*[clinic input]
4693os.rename
4694
4695 src : path_t
4696 dst : path_t
4697 *
4698 src_dir_fd : dir_fd = None
4699 dst_dir_fd : dir_fd = None
4700
4701Rename a file or directory.
4702
4703If either src_dir_fd or dst_dir_fd is not None, it should be a file
4704 descriptor open to a directory, and the respective path string (src or dst)
4705 should be relative; the path will then be relative to that directory.
4706src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4707 If they are unavailable, using them will raise a NotImplementedError.
4708[clinic start generated code]*/
4709
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004710static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004711os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004712 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004713/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004714{
Larry Hastings2f936352014-08-05 14:04:04 +10004715 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004716}
4717
Larry Hastings2f936352014-08-05 14:04:04 +10004718
4719/*[clinic input]
4720os.replace = os.rename
4721
4722Rename a file or directory, overwriting the destination.
4723
4724If either src_dir_fd or dst_dir_fd is not None, it should be a file
4725 descriptor open to a directory, and the respective path string (src or dst)
4726 should be relative; the path will then be relative to that directory.
4727src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004728 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004729[clinic start generated code]*/
4730
Larry Hastings2f936352014-08-05 14:04:04 +10004731static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004732os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4733 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004734/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004735{
4736 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4737}
4738
4739
4740/*[clinic input]
4741os.rmdir
4742
4743 path: path_t
4744 *
4745 dir_fd: dir_fd(requires='unlinkat') = None
4746
4747Remove a directory.
4748
4749If dir_fd is not None, it should be a file descriptor open to a directory,
4750 and path should be relative; path will then be relative to that directory.
4751dir_fd may not be implemented on your platform.
4752 If it is unavailable, using it will raise a NotImplementedError.
4753[clinic start generated code]*/
4754
Larry Hastings2f936352014-08-05 14:04:04 +10004755static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004756os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4757/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004758{
4759 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004760#ifdef HAVE_UNLINKAT
4761 int unlinkat_unavailable = 0;
4762#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004763
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004764 if (PySys_Audit("os.rmdir", "Oi", path->object,
4765 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4766 return NULL;
4767 }
4768
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004769 Py_BEGIN_ALLOW_THREADS
4770#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004771 /* Windows, success=1, UNIX, success=0 */
4772 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004773#else
4774#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004775 if (dir_fd != DEFAULT_DIR_FD) {
4776 if (HAVE_UNLINKAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004777 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Ronald Oussoren41761932020-11-08 10:05:27 +01004778 } else {
4779 unlinkat_unavailable = 1;
4780 result = -1;
4781 }
4782 } else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004783#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004784 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004785#endif
4786 Py_END_ALLOW_THREADS
4787
Ronald Oussoren41761932020-11-08 10:05:27 +01004788#ifdef HAVE_UNLINKAT
4789 if (unlinkat_unavailable) {
4790 argument_unavailable_error("rmdir", "dir_fd");
4791 return NULL;
4792 }
4793#endif
4794
Larry Hastings2f936352014-08-05 14:04:04 +10004795 if (result)
4796 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004797
Larry Hastings2f936352014-08-05 14:04:04 +10004798 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004799}
4800
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004801
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004802#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004803#ifdef MS_WINDOWS
4804/*[clinic input]
4805os.system -> long
4806
4807 command: Py_UNICODE
4808
4809Execute the command in a subshell.
4810[clinic start generated code]*/
4811
Larry Hastings2f936352014-08-05 14:04:04 +10004812static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004813os_system_impl(PyObject *module, const Py_UNICODE *command)
4814/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004815{
4816 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004817
Steve Dowerfbe3c762019-10-18 00:52:15 -07004818 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004819 return -1;
4820 }
4821
Victor Stinner8c62be82010-05-06 00:08:46 +00004822 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004823 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004824 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004825 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004826 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004827 return result;
4828}
4829#else /* MS_WINDOWS */
4830/*[clinic input]
4831os.system -> long
4832
4833 command: FSConverter
4834
4835Execute the command in a subshell.
4836[clinic start generated code]*/
4837
Larry Hastings2f936352014-08-05 14:04:04 +10004838static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004839os_system_impl(PyObject *module, PyObject *command)
4840/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004841{
4842 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004843 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004844
Steve Dowerfbe3c762019-10-18 00:52:15 -07004845 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004846 return -1;
4847 }
4848
Larry Hastings2f936352014-08-05 14:04:04 +10004849 Py_BEGIN_ALLOW_THREADS
4850 result = system(bytes);
4851 Py_END_ALLOW_THREADS
4852 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004853}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004854#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004855#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004856
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004857
Larry Hastings2f936352014-08-05 14:04:04 +10004858/*[clinic input]
4859os.umask
4860
4861 mask: int
4862 /
4863
4864Set the current numeric umask and return the previous umask.
4865[clinic start generated code]*/
4866
Larry Hastings2f936352014-08-05 14:04:04 +10004867static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004868os_umask_impl(PyObject *module, int mask)
4869/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004870{
4871 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004872 if (i < 0)
4873 return posix_error();
4874 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004875}
4876
Brian Curtind40e6f72010-07-08 21:39:08 +00004877#ifdef MS_WINDOWS
4878
4879/* override the default DeleteFileW behavior so that directory
4880symlinks can be removed with this function, the same as with
4881Unix symlinks */
4882BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4883{
4884 WIN32_FILE_ATTRIBUTE_DATA info;
4885 WIN32_FIND_DATAW find_data;
4886 HANDLE find_data_handle;
4887 int is_directory = 0;
4888 int is_link = 0;
4889
4890 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4891 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004892
Brian Curtind40e6f72010-07-08 21:39:08 +00004893 /* Get WIN32_FIND_DATA structure for the path to determine if
4894 it is a symlink */
4895 if(is_directory &&
4896 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4897 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4898
4899 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004900 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4901 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4902 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4903 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004904 FindClose(find_data_handle);
4905 }
4906 }
4907 }
4908
4909 if (is_directory && is_link)
4910 return RemoveDirectoryW(lpFileName);
4911
4912 return DeleteFileW(lpFileName);
4913}
4914#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004915
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004916
Larry Hastings2f936352014-08-05 14:04:04 +10004917/*[clinic input]
4918os.unlink
4919
4920 path: path_t
4921 *
4922 dir_fd: dir_fd(requires='unlinkat')=None
4923
4924Remove a file (same as remove()).
4925
4926If dir_fd is not None, it should be a file descriptor open to a directory,
4927 and path should be relative; path will then be relative to that directory.
4928dir_fd may not be implemented on your platform.
4929 If it is unavailable, using it will raise a NotImplementedError.
4930
4931[clinic start generated code]*/
4932
Larry Hastings2f936352014-08-05 14:04:04 +10004933static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004934os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4935/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004936{
4937 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004938#ifdef HAVE_UNLINKAT
4939 int unlinkat_unavailable = 0;
4940#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004941
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004942 if (PySys_Audit("os.remove", "Oi", path->object,
4943 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4944 return NULL;
4945 }
4946
Larry Hastings9cf065c2012-06-22 16:30:09 -07004947 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004948 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004949#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004950 /* Windows, success=1, UNIX, success=0 */
4951 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004952#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004953#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004954 if (dir_fd != DEFAULT_DIR_FD) {
4955 if (HAVE_UNLINKAT_RUNTIME) {
4956
Larry Hastings2f936352014-08-05 14:04:04 +10004957 result = unlinkat(dir_fd, path->narrow, 0);
Ronald Oussoren41761932020-11-08 10:05:27 +01004958 } else {
4959 unlinkat_unavailable = 1;
4960 }
4961 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004962#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004963 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004964#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004965 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004966 Py_END_ALLOW_THREADS
4967
Ronald Oussoren41761932020-11-08 10:05:27 +01004968#ifdef HAVE_UNLINKAT
4969 if (unlinkat_unavailable) {
4970 argument_unavailable_error(NULL, "dir_fd");
4971 return NULL;
4972 }
4973#endif
4974
Larry Hastings2f936352014-08-05 14:04:04 +10004975 if (result)
4976 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004977
Larry Hastings2f936352014-08-05 14:04:04 +10004978 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004979}
4980
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004981
Larry Hastings2f936352014-08-05 14:04:04 +10004982/*[clinic input]
4983os.remove = os.unlink
4984
4985Remove a file (same as unlink()).
4986
4987If dir_fd is not None, it should be a file descriptor open to a directory,
4988 and path should be relative; path will then be relative to that directory.
4989dir_fd may not be implemented on your platform.
4990 If it is unavailable, using it will raise a NotImplementedError.
4991[clinic start generated code]*/
4992
Larry Hastings2f936352014-08-05 14:04:04 +10004993static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004994os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4995/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004996{
4997 return os_unlink_impl(module, path, dir_fd);
4998}
4999
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005000
Larry Hastings605a62d2012-06-24 04:33:36 -07005001static PyStructSequence_Field uname_result_fields[] = {
5002 {"sysname", "operating system name"},
5003 {"nodename", "name of machine on network (implementation-defined)"},
5004 {"release", "operating system release"},
5005 {"version", "operating system version"},
5006 {"machine", "hardware identifier"},
5007 {NULL}
5008};
5009
5010PyDoc_STRVAR(uname_result__doc__,
5011"uname_result: Result from os.uname().\n\n\
5012This object may be accessed either as a tuple of\n\
5013 (sysname, nodename, release, version, machine),\n\
5014or via the attributes sysname, nodename, release, version, and machine.\n\
5015\n\
5016See os.uname for more information.");
5017
5018static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08005019 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07005020 uname_result__doc__, /* doc */
5021 uname_result_fields,
5022 5
5023};
5024
Larry Hastings605a62d2012-06-24 04:33:36 -07005025#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10005026/*[clinic input]
5027os.uname
5028
5029Return an object identifying the current operating system.
5030
5031The object behaves like a named tuple with the following fields:
5032 (sysname, nodename, release, version, machine)
5033
5034[clinic start generated code]*/
5035
Larry Hastings2f936352014-08-05 14:04:04 +10005036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005037os_uname_impl(PyObject *module)
5038/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00005039{
Victor Stinner8c62be82010-05-06 00:08:46 +00005040 struct utsname u;
5041 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07005042 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00005043
Victor Stinner8c62be82010-05-06 00:08:46 +00005044 Py_BEGIN_ALLOW_THREADS
5045 res = uname(&u);
5046 Py_END_ALLOW_THREADS
5047 if (res < 0)
5048 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07005049
Hai Shif707d942020-03-16 21:15:01 +08005050 PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08005051 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07005052 if (value == NULL)
5053 return NULL;
5054
5055#define SET(i, field) \
5056 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02005057 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07005058 if (!o) { \
5059 Py_DECREF(value); \
5060 return NULL; \
5061 } \
5062 PyStructSequence_SET_ITEM(value, i, o); \
5063 } \
5064
5065 SET(0, u.sysname);
5066 SET(1, u.nodename);
5067 SET(2, u.release);
5068 SET(3, u.version);
5069 SET(4, u.machine);
5070
5071#undef SET
5072
5073 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00005074}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005075#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005076
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005077
Larry Hastings9cf065c2012-06-22 16:30:09 -07005078
5079typedef struct {
5080 int now;
5081 time_t atime_s;
5082 long atime_ns;
5083 time_t mtime_s;
5084 long mtime_ns;
5085} utime_t;
5086
5087/*
Victor Stinner484df002014-10-09 13:52:31 +02005088 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07005089 * they also intentionally leak the declaration of a pointer named "time"
5090 */
5091#define UTIME_TO_TIMESPEC \
5092 struct timespec ts[2]; \
5093 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005094 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005095 time = NULL; \
5096 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005097 ts[0].tv_sec = ut->atime_s; \
5098 ts[0].tv_nsec = ut->atime_ns; \
5099 ts[1].tv_sec = ut->mtime_s; \
5100 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005101 time = ts; \
5102 } \
5103
5104#define UTIME_TO_TIMEVAL \
5105 struct timeval tv[2]; \
5106 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005107 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005108 time = NULL; \
5109 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005110 tv[0].tv_sec = ut->atime_s; \
5111 tv[0].tv_usec = ut->atime_ns / 1000; \
5112 tv[1].tv_sec = ut->mtime_s; \
5113 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005114 time = tv; \
5115 } \
5116
5117#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005118 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005119 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005120 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005121 time = NULL; \
5122 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005123 u.actime = ut->atime_s; \
5124 u.modtime = ut->mtime_s; \
5125 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005126 }
5127
5128#define UTIME_TO_TIME_T \
5129 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005130 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005131 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005132 time = NULL; \
5133 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005134 timet[0] = ut->atime_s; \
5135 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005136 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005137 } \
5138
5139
Victor Stinner528a9ab2015-09-03 21:30:26 +02005140#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005141
5142static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005143utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005144{
Ronald Oussoren41761932020-11-08 10:05:27 +01005145#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5146 if (HAVE_UTIMENSAT_RUNTIME) {
5147 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5148 UTIME_TO_TIMESPEC;
5149 return utimensat(dir_fd, path, time, flags);
5150 } else {
5151 errno = ENOSYS;
5152 return -1;
5153 }
5154#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005155 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5156 UTIME_TO_TIMESPEC;
5157 return utimensat(dir_fd, path, time, flags);
5158#elif defined(HAVE_FUTIMESAT)
5159 UTIME_TO_TIMEVAL;
5160 /*
5161 * follow_symlinks will never be false here;
5162 * we only allow !follow_symlinks and dir_fd together
5163 * if we have utimensat()
5164 */
5165 assert(follow_symlinks);
5166 return futimesat(dir_fd, path, time);
5167#endif
5168}
5169
Larry Hastings2f936352014-08-05 14:04:04 +10005170 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
5171#else
5172 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07005173#endif
5174
Victor Stinner528a9ab2015-09-03 21:30:26 +02005175#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005176
5177static int
Victor Stinner484df002014-10-09 13:52:31 +02005178utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005179{
5180#ifdef HAVE_FUTIMENS
Ronald Oussoren41761932020-11-08 10:05:27 +01005181
5182 if (HAVE_FUTIMENS_RUNTIME) {
5183
Larry Hastings9cf065c2012-06-22 16:30:09 -07005184 UTIME_TO_TIMESPEC;
5185 return futimens(fd, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005186
5187 } else
5188#ifndef HAVE_FUTIMES
5189 {
5190 /* Not sure if this can happen */
5191 PyErr_SetString(
5192 PyExc_RuntimeError,
5193 "neither futimens nor futimes are supported"
5194 " on this system");
5195 return -1;
5196 }
5197#endif
5198
5199#endif
5200#ifdef HAVE_FUTIMES
5201 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005202 UTIME_TO_TIMEVAL;
5203 return futimes(fd, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005204 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005205#endif
5206}
5207
Larry Hastings2f936352014-08-05 14:04:04 +10005208 #define PATH_UTIME_HAVE_FD 1
5209#else
5210 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07005211#endif
5212
Victor Stinner5ebae872015-09-22 01:29:33 +02005213#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
5214# define UTIME_HAVE_NOFOLLOW_SYMLINKS
5215#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005216
Victor Stinner4552ced2015-09-21 22:37:15 +02005217#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005218
5219static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005220utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005221{
5222#ifdef HAVE_UTIMENSAT
Ronald Oussoren41761932020-11-08 10:05:27 +01005223 if (HAVE_UTIMENSAT_RUNTIME) {
5224 UTIME_TO_TIMESPEC;
5225 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
5226 } else
5227#ifndef HAVE_LUTIMES
5228 {
5229 /* Not sure if this can happen */
5230 PyErr_SetString(
5231 PyExc_RuntimeError,
5232 "neither utimensat nor lutimes are supported"
5233 " on this system");
5234 return -1;
5235 }
5236#endif
5237#endif
5238
5239#ifdef HAVE_LUTIMES
5240 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005241 UTIME_TO_TIMEVAL;
5242 return lutimes(path, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005243 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005244#endif
5245}
5246
5247#endif
5248
5249#ifndef MS_WINDOWS
5250
5251static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005252utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005253{
Ronald Oussoren41761932020-11-08 10:05:27 +01005254#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5255 if (HAVE_UTIMENSAT_RUNTIME) {
5256 UTIME_TO_TIMESPEC;
5257 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5258 } else {
5259 UTIME_TO_TIMEVAL;
5260 return utimes(path, time);
5261 }
5262#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005263 UTIME_TO_TIMESPEC;
5264 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5265#elif defined(HAVE_UTIMES)
5266 UTIME_TO_TIMEVAL;
5267 return utimes(path, time);
5268#elif defined(HAVE_UTIME_H)
5269 UTIME_TO_UTIMBUF;
5270 return utime(path, time);
5271#else
5272 UTIME_TO_TIME_T;
5273 return utime(path, time);
5274#endif
5275}
5276
5277#endif
5278
Larry Hastings76ad59b2012-05-03 00:30:07 -07005279static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005280split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
Larry Hastings76ad59b2012-05-03 00:30:07 -07005281{
5282 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04005283 PyObject *divmod;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005284 divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07005285 if (!divmod)
5286 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005287 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
5288 PyErr_Format(PyExc_TypeError,
5289 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08005290 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005291 goto exit;
5292 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005293 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
5294 if ((*s == -1) && PyErr_Occurred())
5295 goto exit;
5296 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04005297 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07005298 goto exit;
5299
5300 result = 1;
5301exit:
5302 Py_XDECREF(divmod);
5303 return result;
5304}
5305
Larry Hastings2f936352014-08-05 14:04:04 +10005306
5307/*[clinic input]
5308os.utime
5309
5310 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005311 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10005312 *
5313 ns: object = NULL
5314 dir_fd: dir_fd(requires='futimensat') = None
5315 follow_symlinks: bool=True
5316
Martin Panter0ff89092015-09-09 01:56:53 +00005317# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10005318
5319Set the access and modified time of path.
5320
5321path may always be specified as a string.
5322On some platforms, path may also be specified as an open file descriptor.
5323 If this functionality is unavailable, using it raises an exception.
5324
5325If times is not None, it must be a tuple (atime, mtime);
5326 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005327If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10005328 atime_ns and mtime_ns should be expressed as integer nanoseconds
5329 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005330If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10005331Specifying tuples for both times and ns is an error.
5332
5333If dir_fd is not None, it should be a file descriptor open to a directory,
5334 and path should be relative; path will then be relative to that directory.
5335If follow_symlinks is False, and the last element of the path is a symbolic
5336 link, utime will modify the symbolic link itself instead of the file the
5337 link points to.
5338It is an error to use dir_fd or follow_symlinks when specifying path
5339 as an open file descriptor.
5340dir_fd and follow_symlinks may not be available on your platform.
5341 If they are unavailable, using them will raise a NotImplementedError.
5342
5343[clinic start generated code]*/
5344
Larry Hastings2f936352014-08-05 14:04:04 +10005345static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005346os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
5347 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005348/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005349{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005350#ifdef MS_WINDOWS
5351 HANDLE hFile;
5352 FILETIME atime, mtime;
5353#else
5354 int result;
5355#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005356
Larry Hastings2f936352014-08-05 14:04:04 +10005357 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005358
Christian Heimesb3c87242013-08-01 00:08:16 +02005359 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07005360
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005361 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005362 PyErr_SetString(PyExc_ValueError,
5363 "utime: you may specify either 'times'"
5364 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005365 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005366 }
5367
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005368 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005369 time_t a_sec, m_sec;
5370 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005371 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005372 PyErr_SetString(PyExc_TypeError,
5373 "utime: 'times' must be either"
5374 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005375 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005376 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005377 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005378 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005379 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005380 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005381 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005382 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005383 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005384 utime.atime_s = a_sec;
5385 utime.atime_ns = a_nsec;
5386 utime.mtime_s = m_sec;
5387 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005388 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005389 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07005390 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005391 PyErr_SetString(PyExc_TypeError,
5392 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005393 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005394 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005395 utime.now = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005396 if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005397 &utime.atime_s, &utime.atime_ns) ||
Victor Stinner1c2fa782020-05-10 11:05:29 +02005398 !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005399 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005400 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005401 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005402 }
5403 else {
5404 /* times and ns are both None/unspecified. use "now". */
5405 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005406 }
5407
Victor Stinner4552ced2015-09-21 22:37:15 +02005408#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005409 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005410 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005411#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005412
Larry Hastings2f936352014-08-05 14:04:04 +10005413 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
5414 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
5415 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005416 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005417
Larry Hastings9cf065c2012-06-22 16:30:09 -07005418#if !defined(HAVE_UTIMENSAT)
5419 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02005420 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005421 "utime: cannot use dir_fd and follow_symlinks "
5422 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005423 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005424 }
5425#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005426
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005427 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
5428 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
5429 return NULL;
5430 }
5431
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005432#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005433 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005434 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5435 NULL, OPEN_EXISTING,
5436 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005437 Py_END_ALLOW_THREADS
5438 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005439 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005440 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005441 }
5442
Larry Hastings9cf065c2012-06-22 16:30:09 -07005443 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005444 GetSystemTimeAsFileTime(&mtime);
5445 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005446 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005447 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005448 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5449 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005450 }
5451 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5452 /* Avoid putting the file name into the error here,
5453 as that may confuse the user into believing that
5454 something is wrong with the file, when it also
5455 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005456 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005457 CloseHandle(hFile);
5458 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005459 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005460 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005461#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005462 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005463
Victor Stinner4552ced2015-09-21 22:37:15 +02005464#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005465 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005466 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005467 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005468#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005469
Victor Stinner528a9ab2015-09-03 21:30:26 +02005470#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Ronald Oussoren41761932020-11-08 10:05:27 +01005471 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
Larry Hastings2f936352014-08-05 14:04:04 +10005472 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Ronald Oussoren41761932020-11-08 10:05:27 +01005473
5474 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07005475#endif
5476
Victor Stinner528a9ab2015-09-03 21:30:26 +02005477#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005478 if (path->fd != -1)
5479 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005480 else
5481#endif
5482
Larry Hastings2f936352014-08-05 14:04:04 +10005483 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005484
5485 Py_END_ALLOW_THREADS
5486
Ronald Oussoren41761932020-11-08 10:05:27 +01005487#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5488 /* See utime_dir_fd implementation */
5489 if (result == -1 && errno == ENOSYS) {
5490 argument_unavailable_error(NULL, "dir_fd");
5491 return NULL;
5492 }
5493#endif
5494
Larry Hastings9cf065c2012-06-22 16:30:09 -07005495 if (result < 0) {
5496 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005497 posix_error();
5498 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005499 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005500
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005501#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005502
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005503 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005504}
5505
Guido van Rossum3b066191991-06-04 19:40:25 +00005506/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005507
Larry Hastings2f936352014-08-05 14:04:04 +10005508
5509/*[clinic input]
5510os._exit
5511
5512 status: int
5513
5514Exit to the system with specified status, without normal exit processing.
5515[clinic start generated code]*/
5516
Larry Hastings2f936352014-08-05 14:04:04 +10005517static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005518os__exit_impl(PyObject *module, int status)
5519/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005520{
5521 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005522 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005523}
5524
Steve Dowercc16be82016-09-08 10:35:16 -07005525#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5526#define EXECV_CHAR wchar_t
5527#else
5528#define EXECV_CHAR char
5529#endif
5530
pxinwrf2d7ac72019-05-21 18:46:37 +08005531#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005532static void
Steve Dowercc16be82016-09-08 10:35:16 -07005533free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005534{
Victor Stinner8c62be82010-05-06 00:08:46 +00005535 Py_ssize_t i;
5536 for (i = 0; i < count; i++)
5537 PyMem_Free(array[i]);
Victor Stinner00d7abd2020-12-01 09:56:42 +01005538 PyMem_Free(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005539}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005540
Berker Peksag81816462016-09-15 20:19:47 +03005541static int
5542fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005543{
Victor Stinner8c62be82010-05-06 00:08:46 +00005544 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005545 PyObject *ub;
5546 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005547#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005548 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005549 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005550 *out = PyUnicode_AsWideCharString(ub, &size);
5551 if (*out)
5552 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005553#else
Berker Peksag81816462016-09-15 20:19:47 +03005554 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005555 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005556 size = PyBytes_GET_SIZE(ub);
5557 *out = PyMem_Malloc(size + 1);
5558 if (*out) {
5559 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5560 result = 1;
5561 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005562 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005563#endif
Berker Peksag81816462016-09-15 20:19:47 +03005564 Py_DECREF(ub);
5565 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005566}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005567#endif
5568
pxinwrf2d7ac72019-05-21 18:46:37 +08005569#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005570static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005571parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5572{
Victor Stinner8c62be82010-05-06 00:08:46 +00005573 Py_ssize_t i, pos, envc;
5574 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005575 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005576 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005577
Victor Stinner8c62be82010-05-06 00:08:46 +00005578 i = PyMapping_Size(env);
5579 if (i < 0)
5580 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005581 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005582 if (envlist == NULL) {
5583 PyErr_NoMemory();
5584 return NULL;
5585 }
5586 envc = 0;
5587 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005588 if (!keys)
5589 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005590 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005591 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005592 goto error;
5593 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5594 PyErr_Format(PyExc_TypeError,
5595 "env.keys() or env.values() is not a list");
5596 goto error;
5597 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005598
Victor Stinner8c62be82010-05-06 00:08:46 +00005599 for (pos = 0; pos < i; pos++) {
5600 key = PyList_GetItem(keys, pos);
5601 val = PyList_GetItem(vals, pos);
5602 if (!key || !val)
5603 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005604
Berker Peksag81816462016-09-15 20:19:47 +03005605#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5606 if (!PyUnicode_FSDecoder(key, &key2))
5607 goto error;
5608 if (!PyUnicode_FSDecoder(val, &val2)) {
5609 Py_DECREF(key2);
5610 goto error;
5611 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005612 /* Search from index 1 because on Windows starting '=' is allowed for
5613 defining hidden environment variables. */
5614 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5615 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5616 {
5617 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005618 Py_DECREF(key2);
5619 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005620 goto error;
5621 }
Berker Peksag81816462016-09-15 20:19:47 +03005622 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5623#else
5624 if (!PyUnicode_FSConverter(key, &key2))
5625 goto error;
5626 if (!PyUnicode_FSConverter(val, &val2)) {
5627 Py_DECREF(key2);
5628 goto error;
5629 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005630 if (PyBytes_GET_SIZE(key2) == 0 ||
5631 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5632 {
5633 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005634 Py_DECREF(key2);
5635 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005636 goto error;
5637 }
Berker Peksag81816462016-09-15 20:19:47 +03005638 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5639 PyBytes_AS_STRING(val2));
5640#endif
5641 Py_DECREF(key2);
5642 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005643 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005644 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005645
5646 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5647 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005648 goto error;
5649 }
Berker Peksag81816462016-09-15 20:19:47 +03005650
Steve Dowercc16be82016-09-08 10:35:16 -07005651 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005652 }
5653 Py_DECREF(vals);
5654 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005655
Victor Stinner8c62be82010-05-06 00:08:46 +00005656 envlist[envc] = 0;
5657 *envc_ptr = envc;
5658 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005659
5660error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005661 Py_XDECREF(keys);
5662 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005663 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005664 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005665}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005666
Steve Dowercc16be82016-09-08 10:35:16 -07005667static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005668parse_arglist(PyObject* argv, Py_ssize_t *argc)
5669{
5670 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005671 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005672 if (argvlist == NULL) {
5673 PyErr_NoMemory();
5674 return NULL;
5675 }
5676 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005677 PyObject* item = PySequence_ITEM(argv, i);
5678 if (item == NULL)
5679 goto fail;
5680 if (!fsconvert_strdup(item, &argvlist[i])) {
5681 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005682 goto fail;
5683 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005684 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005685 }
5686 argvlist[*argc] = NULL;
5687 return argvlist;
5688fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005689 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005690 free_string_array(argvlist, *argc);
5691 return NULL;
5692}
Steve Dowercc16be82016-09-08 10:35:16 -07005693
Ross Lagerwall7807c352011-03-17 20:20:30 +02005694#endif
5695
Larry Hastings2f936352014-08-05 14:04:04 +10005696
Ross Lagerwall7807c352011-03-17 20:20:30 +02005697#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005698/*[clinic input]
5699os.execv
5700
Steve Dowercc16be82016-09-08 10:35:16 -07005701 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005702 Path of executable file.
5703 argv: object
5704 Tuple or list of strings.
5705 /
5706
5707Execute an executable path with arguments, replacing current process.
5708[clinic start generated code]*/
5709
Larry Hastings2f936352014-08-05 14:04:04 +10005710static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005711os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5712/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005713{
Steve Dowercc16be82016-09-08 10:35:16 -07005714 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005715 Py_ssize_t argc;
5716
5717 /* execv has two arguments: (path, argv), where
5718 argv is a list or tuple of strings. */
5719
Ross Lagerwall7807c352011-03-17 20:20:30 +02005720 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5721 PyErr_SetString(PyExc_TypeError,
5722 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005723 return NULL;
5724 }
5725 argc = PySequence_Size(argv);
5726 if (argc < 1) {
5727 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005728 return NULL;
5729 }
5730
5731 argvlist = parse_arglist(argv, &argc);
5732 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005733 return NULL;
5734 }
Steve Dowerbce26262016-11-19 19:17:26 -08005735 if (!argvlist[0][0]) {
5736 PyErr_SetString(PyExc_ValueError,
5737 "execv() arg 2 first element cannot be empty");
5738 free_string_array(argvlist, argc);
5739 return NULL;
5740 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005741
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005742 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005743 free_string_array(argvlist, argc);
5744 return NULL;
5745 }
5746
Steve Dowerbce26262016-11-19 19:17:26 -08005747 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005748#ifdef HAVE_WEXECV
5749 _wexecv(path->wide, argvlist);
5750#else
5751 execv(path->narrow, argvlist);
5752#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005753 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005754
5755 /* If we get here it's definitely an error */
5756
5757 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005758 return posix_error();
5759}
5760
Larry Hastings2f936352014-08-05 14:04:04 +10005761
5762/*[clinic input]
5763os.execve
5764
5765 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5766 Path of executable file.
5767 argv: object
5768 Tuple or list of strings.
5769 env: object
5770 Dictionary of strings mapping to strings.
5771
5772Execute an executable path with arguments, replacing current process.
5773[clinic start generated code]*/
5774
Larry Hastings2f936352014-08-05 14:04:04 +10005775static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005776os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5777/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005778{
Steve Dowercc16be82016-09-08 10:35:16 -07005779 EXECV_CHAR **argvlist = NULL;
5780 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005781 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005782
Victor Stinner8c62be82010-05-06 00:08:46 +00005783 /* execve has three arguments: (path, argv, env), where
5784 argv is a list or tuple of strings and env is a dictionary
5785 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005786
Ross Lagerwall7807c352011-03-17 20:20:30 +02005787 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005788 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005789 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005790 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005791 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005792 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005793 if (argc < 1) {
5794 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5795 return NULL;
5796 }
5797
Victor Stinner8c62be82010-05-06 00:08:46 +00005798 if (!PyMapping_Check(env)) {
5799 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005800 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005801 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005802 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005803
Ross Lagerwall7807c352011-03-17 20:20:30 +02005804 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005805 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005806 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005807 }
Steve Dowerbce26262016-11-19 19:17:26 -08005808 if (!argvlist[0][0]) {
5809 PyErr_SetString(PyExc_ValueError,
5810 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005811 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005812 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005813
Victor Stinner8c62be82010-05-06 00:08:46 +00005814 envlist = parse_envlist(env, &envc);
5815 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005816 goto fail_0;
5817
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005818 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005819 goto fail_1;
5820 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005821
Steve Dowerbce26262016-11-19 19:17:26 -08005822 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005823#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005824 if (path->fd > -1)
5825 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005826 else
5827#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005828#ifdef HAVE_WEXECV
5829 _wexecve(path->wide, argvlist, envlist);
5830#else
Larry Hastings2f936352014-08-05 14:04:04 +10005831 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005832#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005833 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005834
5835 /* If we get here it's definitely an error */
5836
Alexey Izbyshev83460312018-10-20 03:28:22 +03005837 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005838 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005839 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005840 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005841 if (argvlist)
5842 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005843 return NULL;
5844}
Steve Dowercc16be82016-09-08 10:35:16 -07005845
Larry Hastings9cf065c2012-06-22 16:30:09 -07005846#endif /* HAVE_EXECV */
5847
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005848#ifdef HAVE_POSIX_SPAWN
5849
5850enum posix_spawn_file_actions_identifier {
5851 POSIX_SPAWN_OPEN,
5852 POSIX_SPAWN_CLOSE,
5853 POSIX_SPAWN_DUP2
5854};
5855
William Orr81574b82018-10-01 22:19:56 -07005856#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005857static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005858convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005859#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005860
5861static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005862parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005863 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005864 PyObject *setsigdef, PyObject *scheduler,
5865 posix_spawnattr_t *attrp)
5866{
5867 long all_flags = 0;
5868
5869 errno = posix_spawnattr_init(attrp);
5870 if (errno) {
5871 posix_error();
5872 return -1;
5873 }
5874
5875 if (setpgroup) {
5876 pid_t pgid = PyLong_AsPid(setpgroup);
5877 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5878 goto fail;
5879 }
5880 errno = posix_spawnattr_setpgroup(attrp, pgid);
5881 if (errno) {
5882 posix_error();
5883 goto fail;
5884 }
5885 all_flags |= POSIX_SPAWN_SETPGROUP;
5886 }
5887
5888 if (resetids) {
5889 all_flags |= POSIX_SPAWN_RESETIDS;
5890 }
5891
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005892 if (setsid) {
Ronald Oussoren41761932020-11-08 10:05:27 +01005893#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5894 if (HAVE_POSIX_SPAWN_SETSID_RUNTIME) {
5895#endif
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005896#ifdef POSIX_SPAWN_SETSID
5897 all_flags |= POSIX_SPAWN_SETSID;
5898#elif defined(POSIX_SPAWN_SETSID_NP)
5899 all_flags |= POSIX_SPAWN_SETSID_NP;
5900#else
5901 argument_unavailable_error(func_name, "setsid");
5902 return -1;
5903#endif
Ronald Oussoren41761932020-11-08 10:05:27 +01005904
5905#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5906 } else {
5907 argument_unavailable_error(func_name, "setsid");
5908 return -1;
5909 }
5910#endif /* HAVE_POSIX_SPAWN_SETSID_RUNTIME */
5911
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005912 }
5913
Pablo Galindo254a4662018-09-07 16:44:24 +01005914 if (setsigmask) {
5915 sigset_t set;
5916 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5917 goto fail;
5918 }
5919 errno = posix_spawnattr_setsigmask(attrp, &set);
5920 if (errno) {
5921 posix_error();
5922 goto fail;
5923 }
5924 all_flags |= POSIX_SPAWN_SETSIGMASK;
5925 }
5926
5927 if (setsigdef) {
5928 sigset_t set;
5929 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5930 goto fail;
5931 }
5932 errno = posix_spawnattr_setsigdefault(attrp, &set);
5933 if (errno) {
5934 posix_error();
5935 goto fail;
5936 }
5937 all_flags |= POSIX_SPAWN_SETSIGDEF;
5938 }
5939
5940 if (scheduler) {
5941#ifdef POSIX_SPAWN_SETSCHEDULER
5942 PyObject *py_schedpolicy;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005943 PyObject *schedparam_obj;
Pablo Galindo254a4662018-09-07 16:44:24 +01005944 struct sched_param schedparam;
5945
Victor Stinner1c2fa782020-05-10 11:05:29 +02005946 if (!PyArg_ParseTuple(scheduler, "OO"
Pablo Galindo254a4662018-09-07 16:44:24 +01005947 ";A scheduler tuple must have two elements",
Victor Stinner1c2fa782020-05-10 11:05:29 +02005948 &py_schedpolicy, &schedparam_obj)) {
5949 goto fail;
5950 }
5951 if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005952 goto fail;
5953 }
5954 if (py_schedpolicy != Py_None) {
5955 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5956
5957 if (schedpolicy == -1 && PyErr_Occurred()) {
5958 goto fail;
5959 }
5960 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5961 if (errno) {
5962 posix_error();
5963 goto fail;
5964 }
5965 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5966 }
5967 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5968 if (errno) {
5969 posix_error();
5970 goto fail;
5971 }
5972 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5973#else
5974 PyErr_SetString(PyExc_NotImplementedError,
5975 "The scheduler option is not supported in this system.");
5976 goto fail;
5977#endif
5978 }
5979
5980 errno = posix_spawnattr_setflags(attrp, all_flags);
5981 if (errno) {
5982 posix_error();
5983 goto fail;
5984 }
5985
5986 return 0;
5987
5988fail:
5989 (void)posix_spawnattr_destroy(attrp);
5990 return -1;
5991}
5992
5993static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005994parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005995 posix_spawn_file_actions_t *file_actionsp,
5996 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005997{
5998 PyObject *seq;
5999 PyObject *file_action = NULL;
6000 PyObject *tag_obj;
6001
6002 seq = PySequence_Fast(file_actions,
6003 "file_actions must be a sequence or None");
6004 if (seq == NULL) {
6005 return -1;
6006 }
6007
6008 errno = posix_spawn_file_actions_init(file_actionsp);
6009 if (errno) {
6010 posix_error();
6011 Py_DECREF(seq);
6012 return -1;
6013 }
6014
Zackery Spytzd52a83a2019-06-26 14:54:20 -06006015 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03006016 file_action = PySequence_Fast_GET_ITEM(seq, i);
6017 Py_INCREF(file_action);
6018 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
6019 PyErr_SetString(PyExc_TypeError,
6020 "Each file_actions element must be a non-empty tuple");
6021 goto fail;
6022 }
6023 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
6024 if (tag == -1 && PyErr_Occurred()) {
6025 goto fail;
6026 }
6027
6028 /* Populate the file_actions object */
6029 switch (tag) {
6030 case POSIX_SPAWN_OPEN: {
6031 int fd, oflag;
6032 PyObject *path;
6033 unsigned long mode;
6034 if (!PyArg_ParseTuple(file_action, "OiO&ik"
6035 ";A open file_action tuple must have 5 elements",
6036 &tag_obj, &fd, PyUnicode_FSConverter, &path,
6037 &oflag, &mode))
6038 {
6039 goto fail;
6040 }
Pablo Galindocb970732018-06-19 09:19:50 +01006041 if (PyList_Append(temp_buffer, path)) {
6042 Py_DECREF(path);
6043 goto fail;
6044 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03006045 errno = posix_spawn_file_actions_addopen(file_actionsp,
6046 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01006047 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03006048 if (errno) {
6049 posix_error();
6050 goto fail;
6051 }
6052 break;
6053 }
6054 case POSIX_SPAWN_CLOSE: {
6055 int fd;
6056 if (!PyArg_ParseTuple(file_action, "Oi"
6057 ";A close file_action tuple must have 2 elements",
6058 &tag_obj, &fd))
6059 {
6060 goto fail;
6061 }
6062 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
6063 if (errno) {
6064 posix_error();
6065 goto fail;
6066 }
6067 break;
6068 }
6069 case POSIX_SPAWN_DUP2: {
6070 int fd1, fd2;
6071 if (!PyArg_ParseTuple(file_action, "Oii"
6072 ";A dup2 file_action tuple must have 3 elements",
6073 &tag_obj, &fd1, &fd2))
6074 {
6075 goto fail;
6076 }
6077 errno = posix_spawn_file_actions_adddup2(file_actionsp,
6078 fd1, fd2);
6079 if (errno) {
6080 posix_error();
6081 goto fail;
6082 }
6083 break;
6084 }
6085 default: {
6086 PyErr_SetString(PyExc_TypeError,
6087 "Unknown file_actions identifier");
6088 goto fail;
6089 }
6090 }
6091 Py_DECREF(file_action);
6092 }
Pablo Galindo254a4662018-09-07 16:44:24 +01006093
Serhiy Storchakaef347532018-05-01 16:45:04 +03006094 Py_DECREF(seq);
6095 return 0;
6096
6097fail:
6098 Py_DECREF(seq);
6099 Py_DECREF(file_action);
6100 (void)posix_spawn_file_actions_destroy(file_actionsp);
6101 return -1;
6102}
6103
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006104
6105static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006106py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
6107 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006108 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006109 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006110{
Victor Stinner325e4ba2019-02-01 15:47:24 +01006111 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006112 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006113 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006114 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006115 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01006116 posix_spawnattr_t attr;
6117 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006118 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006119 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01006120 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006121 pid_t pid;
6122 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006123
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006124 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03006125 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006126 like posix.environ. */
6127
Serhiy Storchakaef347532018-05-01 16:45:04 +03006128 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006129 PyErr_Format(PyExc_TypeError,
6130 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006131 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006132 }
6133 argc = PySequence_Size(argv);
6134 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006135 PyErr_Format(PyExc_ValueError,
6136 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006137 return NULL;
6138 }
6139
6140 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006141 PyErr_Format(PyExc_TypeError,
6142 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006143 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006144 }
6145
6146 argvlist = parse_arglist(argv, &argc);
6147 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006148 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006149 }
6150 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006151 PyErr_Format(PyExc_ValueError,
6152 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006153 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006154 }
6155
6156 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006157 if (envlist == NULL) {
6158 goto exit;
6159 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006160
Anthony Shaw948ed8c2019-05-10 12:00:06 +10006161 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01006162 /* There is a bug in old versions of glibc that makes some of the
6163 * helper functions for manipulating file actions not copy the provided
6164 * buffers. The problem is that posix_spawn_file_actions_addopen does not
6165 * copy the value of path for some old versions of glibc (<2.20).
6166 * The use of temp_buffer here is a workaround that keeps the
6167 * python objects that own the buffers alive until posix_spawn gets called.
6168 * Check https://bugs.python.org/issue33630 and
6169 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
6170 temp_buffer = PyList_New(0);
6171 if (!temp_buffer) {
6172 goto exit;
6173 }
6174 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006175 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006176 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03006177 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006178 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006179
Victor Stinner1c2fa782020-05-10 11:05:29 +02006180 if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
Victor Stinner325e4ba2019-02-01 15:47:24 +01006181 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01006182 goto exit;
6183 }
6184 attrp = &attr;
6185
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006186 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006187 goto exit;
6188 }
6189
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006190 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006191#ifdef HAVE_POSIX_SPAWNP
6192 if (use_posix_spawnp) {
6193 err_code = posix_spawnp(&pid, path->narrow,
6194 file_actionsp, attrp, argvlist, envlist);
6195 }
6196 else
6197#endif /* HAVE_POSIX_SPAWNP */
6198 {
6199 err_code = posix_spawn(&pid, path->narrow,
6200 file_actionsp, attrp, argvlist, envlist);
6201 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006202 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006203
Serhiy Storchakaef347532018-05-01 16:45:04 +03006204 if (err_code) {
6205 errno = err_code;
6206 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006207 goto exit;
6208 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006209#ifdef _Py_MEMORY_SANITIZER
6210 __msan_unpoison(&pid, sizeof(pid));
6211#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006212 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006213
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006214exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03006215 if (file_actionsp) {
6216 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006217 }
Pablo Galindo254a4662018-09-07 16:44:24 +01006218 if (attrp) {
6219 (void)posix_spawnattr_destroy(attrp);
6220 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006221 if (envlist) {
6222 free_string_array(envlist, envc);
6223 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006224 if (argvlist) {
6225 free_string_array(argvlist, argc);
6226 }
Pablo Galindocb970732018-06-19 09:19:50 +01006227 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006228 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006229}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006230
6231
6232/*[clinic input]
6233
6234os.posix_spawn
6235 path: path_t
6236 Path of executable file.
6237 argv: object
6238 Tuple or list of strings.
6239 env: object
6240 Dictionary of strings mapping to strings.
6241 /
6242 *
6243 file_actions: object(c_default='NULL') = ()
6244 A sequence of file action tuples.
6245 setpgroup: object = NULL
6246 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6247 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006248 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
6249 setsid: bool(accept={int}) = False
6250 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006251 setsigmask: object(c_default='NULL') = ()
6252 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6253 setsigdef: object(c_default='NULL') = ()
6254 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6255 scheduler: object = NULL
6256 A tuple with the scheduler policy (optional) and parameters.
6257
6258Execute the program specified by path in a new process.
6259[clinic start generated code]*/
6260
6261static PyObject *
6262os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
6263 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006264 PyObject *setpgroup, int resetids, int setsid,
6265 PyObject *setsigmask, PyObject *setsigdef,
6266 PyObject *scheduler)
6267/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006268{
6269 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006270 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006271 scheduler);
6272}
6273 #endif /* HAVE_POSIX_SPAWN */
6274
6275
6276
6277#ifdef HAVE_POSIX_SPAWNP
6278/*[clinic input]
6279
6280os.posix_spawnp
6281 path: path_t
6282 Path of executable file.
6283 argv: object
6284 Tuple or list of strings.
6285 env: object
6286 Dictionary of strings mapping to strings.
6287 /
6288 *
6289 file_actions: object(c_default='NULL') = ()
6290 A sequence of file action tuples.
6291 setpgroup: object = NULL
6292 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6293 resetids: bool(accept={int}) = False
6294 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006295 setsid: bool(accept={int}) = False
6296 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006297 setsigmask: object(c_default='NULL') = ()
6298 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6299 setsigdef: object(c_default='NULL') = ()
6300 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6301 scheduler: object = NULL
6302 A tuple with the scheduler policy (optional) and parameters.
6303
6304Execute the program specified by path in a new process.
6305[clinic start generated code]*/
6306
6307static PyObject *
6308os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
6309 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006310 PyObject *setpgroup, int resetids, int setsid,
6311 PyObject *setsigmask, PyObject *setsigdef,
6312 PyObject *scheduler)
6313/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006314{
6315 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006316 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006317 scheduler);
6318}
6319#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006320
pxinwrf2d7ac72019-05-21 18:46:37 +08006321#ifdef HAVE_RTPSPAWN
6322static intptr_t
6323_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
6324 const char *envp[])
6325{
6326 RTP_ID rtpid;
6327 int status;
6328 pid_t res;
6329 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006330
pxinwrf2d7ac72019-05-21 18:46:37 +08006331 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
6332 uStackSize=0 cannot be used, the default stack size is too small for
6333 Python. */
6334 if (envp) {
6335 rtpid = rtpSpawn(rtpFileName, argv, envp,
6336 100, 0x1000000, 0, VX_FP_TASK);
6337 }
6338 else {
6339 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
6340 100, 0x1000000, 0, VX_FP_TASK);
6341 }
6342 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
6343 do {
6344 res = waitpid((pid_t)rtpid, &status, 0);
6345 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6346
6347 if (res < 0)
6348 return RTP_ID_ERROR;
6349 return ((intptr_t)status);
6350 }
6351 return ((intptr_t)rtpid);
6352}
6353#endif
6354
6355#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10006356/*[clinic input]
6357os.spawnv
6358
6359 mode: int
6360 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006361 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006362 Path of executable file.
6363 argv: object
6364 Tuple or list of strings.
6365 /
6366
6367Execute the program specified by path in a new process.
6368[clinic start generated code]*/
6369
Larry Hastings2f936352014-08-05 14:04:04 +10006370static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006371os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
6372/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006373{
Steve Dowercc16be82016-09-08 10:35:16 -07006374 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10006375 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00006376 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006377 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006378 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00006379
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 /* spawnv has three arguments: (mode, path, argv), where
6381 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006382
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 if (PyList_Check(argv)) {
6384 argc = PyList_Size(argv);
6385 getitem = PyList_GetItem;
6386 }
6387 else if (PyTuple_Check(argv)) {
6388 argc = PyTuple_Size(argv);
6389 getitem = PyTuple_GetItem;
6390 }
6391 else {
6392 PyErr_SetString(PyExc_TypeError,
6393 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00006394 return NULL;
6395 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006396 if (argc == 0) {
6397 PyErr_SetString(PyExc_ValueError,
6398 "spawnv() arg 2 cannot be empty");
6399 return NULL;
6400 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006401
Steve Dowercc16be82016-09-08 10:35:16 -07006402 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006403 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006404 return PyErr_NoMemory();
6405 }
6406 for (i = 0; i < argc; i++) {
6407 if (!fsconvert_strdup((*getitem)(argv, i),
6408 &argvlist[i])) {
6409 free_string_array(argvlist, i);
6410 PyErr_SetString(
6411 PyExc_TypeError,
6412 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 return NULL;
6414 }
Steve Dower93ff8722016-11-19 19:03:54 -08006415 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02006416 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08006417 PyErr_SetString(
6418 PyExc_ValueError,
6419 "spawnv() arg 2 first element cannot be empty");
6420 return NULL;
6421 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 }
6423 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006424
pxinwrf2d7ac72019-05-21 18:46:37 +08006425#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 if (mode == _OLD_P_OVERLAY)
6427 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006428#endif
Tim Peters5aa91602002-01-30 05:46:57 +00006429
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006430 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08006431 Py_None) < 0) {
6432 free_string_array(argvlist, argc);
6433 return NULL;
6434 }
6435
Victor Stinner8c62be82010-05-06 00:08:46 +00006436 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006437 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006438#ifdef HAVE_WSPAWNV
6439 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006440#elif defined(HAVE_RTPSPAWN)
6441 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07006442#else
6443 spawnval = _spawnv(mode, path->narrow, argvlist);
6444#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006445 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00006447
Victor Stinner8c62be82010-05-06 00:08:46 +00006448 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00006449
Victor Stinner8c62be82010-05-06 00:08:46 +00006450 if (spawnval == -1)
6451 return posix_error();
6452 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006453 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006454}
6455
Larry Hastings2f936352014-08-05 14:04:04 +10006456/*[clinic input]
6457os.spawnve
6458
6459 mode: int
6460 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006461 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006462 Path of executable file.
6463 argv: object
6464 Tuple or list of strings.
6465 env: object
6466 Dictionary of strings mapping to strings.
6467 /
6468
6469Execute the program specified by path in a new process.
6470[clinic start generated code]*/
6471
Larry Hastings2f936352014-08-05 14:04:04 +10006472static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006473os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006474 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006475/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006476{
Steve Dowercc16be82016-09-08 10:35:16 -07006477 EXECV_CHAR **argvlist;
6478 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006479 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006480 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006481 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006482 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006483 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006484
Victor Stinner8c62be82010-05-06 00:08:46 +00006485 /* spawnve has four arguments: (mode, path, argv, env), where
6486 argv is a list or tuple of strings and env is a dictionary
6487 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006488
Victor Stinner8c62be82010-05-06 00:08:46 +00006489 if (PyList_Check(argv)) {
6490 argc = PyList_Size(argv);
6491 getitem = PyList_GetItem;
6492 }
6493 else if (PyTuple_Check(argv)) {
6494 argc = PyTuple_Size(argv);
6495 getitem = PyTuple_GetItem;
6496 }
6497 else {
6498 PyErr_SetString(PyExc_TypeError,
6499 "spawnve() arg 2 must be a tuple or list");
6500 goto fail_0;
6501 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006502 if (argc == 0) {
6503 PyErr_SetString(PyExc_ValueError,
6504 "spawnve() arg 2 cannot be empty");
6505 goto fail_0;
6506 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 if (!PyMapping_Check(env)) {
6508 PyErr_SetString(PyExc_TypeError,
6509 "spawnve() arg 3 must be a mapping object");
6510 goto fail_0;
6511 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006512
Steve Dowercc16be82016-09-08 10:35:16 -07006513 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 if (argvlist == NULL) {
6515 PyErr_NoMemory();
6516 goto fail_0;
6517 }
6518 for (i = 0; i < argc; i++) {
6519 if (!fsconvert_strdup((*getitem)(argv, i),
6520 &argvlist[i]))
6521 {
6522 lastarg = i;
6523 goto fail_1;
6524 }
Steve Dowerbce26262016-11-19 19:17:26 -08006525 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006526 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006527 PyErr_SetString(
6528 PyExc_ValueError,
6529 "spawnv() arg 2 first element cannot be empty");
6530 goto fail_1;
6531 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006532 }
6533 lastarg = argc;
6534 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006535
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 envlist = parse_envlist(env, &envc);
6537 if (envlist == NULL)
6538 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006539
pxinwrf2d7ac72019-05-21 18:46:37 +08006540#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006541 if (mode == _OLD_P_OVERLAY)
6542 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006543#endif
Tim Peters25059d32001-12-07 20:35:43 +00006544
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006545 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006546 goto fail_2;
6547 }
6548
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006550 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006551#ifdef HAVE_WSPAWNV
6552 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006553#elif defined(HAVE_RTPSPAWN)
6554 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6555 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006556#else
6557 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6558#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006559 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006561
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 if (spawnval == -1)
6563 (void) posix_error();
6564 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006565 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006566
Saiyang Gou95f60012020-02-04 16:15:00 -08006567 fail_2:
Victor Stinner00d7abd2020-12-01 09:56:42 +01006568 while (--envc >= 0) {
6569 PyMem_Free(envlist[envc]);
6570 }
6571 PyMem_Free(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006572 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006573 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006574 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006576}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006577
Guido van Rossuma1065681999-01-25 23:20:23 +00006578#endif /* HAVE_SPAWNV */
6579
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006580#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006581
6582/* Helper function to validate arguments.
6583 Returns 0 on success. non-zero on failure with a TypeError raised.
6584 If obj is non-NULL it must be callable. */
6585static int
6586check_null_or_callable(PyObject *obj, const char* obj_name)
6587{
6588 if (obj && !PyCallable_Check(obj)) {
6589 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006590 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006591 return -1;
6592 }
6593 return 0;
6594}
6595
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006596/*[clinic input]
6597os.register_at_fork
6598
Gregory P. Smith163468a2017-05-29 10:03:41 -07006599 *
6600 before: object=NULL
6601 A callable to be called in the parent before the fork() syscall.
6602 after_in_child: object=NULL
6603 A callable to be called in the child after fork().
6604 after_in_parent: object=NULL
6605 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006606
Gregory P. Smith163468a2017-05-29 10:03:41 -07006607Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006608
Gregory P. Smith163468a2017-05-29 10:03:41 -07006609'before' callbacks are called in reverse order.
6610'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006611
6612[clinic start generated code]*/
6613
6614static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006615os_register_at_fork_impl(PyObject *module, PyObject *before,
6616 PyObject *after_in_child, PyObject *after_in_parent)
6617/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006618{
6619 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006620
Gregory P. Smith163468a2017-05-29 10:03:41 -07006621 if (!before && !after_in_child && !after_in_parent) {
6622 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6623 return NULL;
6624 }
6625 if (check_null_or_callable(before, "before") ||
6626 check_null_or_callable(after_in_child, "after_in_child") ||
6627 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006628 return NULL;
6629 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006630 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006631
Gregory P. Smith163468a2017-05-29 10:03:41 -07006632 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006633 return NULL;
6634 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006635 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006636 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006637 }
6638 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6639 return NULL;
6640 }
6641 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006642}
6643#endif /* HAVE_FORK */
6644
6645
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006646#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006647/*[clinic input]
6648os.fork1
6649
6650Fork a child process with a single multiplexed (i.e., not bound) thread.
6651
6652Return 0 to child process and PID of child to parent process.
6653[clinic start generated code]*/
6654
Larry Hastings2f936352014-08-05 14:04:04 +10006655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006656os_fork1_impl(PyObject *module)
6657/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006658{
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006660
Victor Stinner81a7be32020-04-14 15:14:01 +02006661 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006662 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6663 return NULL;
6664 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006665 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006666 pid = fork1();
6667 if (pid == 0) {
6668 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006669 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 } else {
6671 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006672 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006673 }
6674 if (pid == -1)
6675 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006676 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006677}
Larry Hastings2f936352014-08-05 14:04:04 +10006678#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006679
6680
Guido van Rossumad0ee831995-03-01 10:34:45 +00006681#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006682/*[clinic input]
6683os.fork
6684
6685Fork a child process.
6686
6687Return 0 to child process and PID of child to parent process.
6688[clinic start generated code]*/
6689
Larry Hastings2f936352014-08-05 14:04:04 +10006690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006691os_fork_impl(PyObject *module)
6692/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006693{
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006695 PyInterpreterState *interp = _PyInterpreterState_GET();
6696 if (interp->config._isolated_interpreter) {
6697 PyErr_SetString(PyExc_RuntimeError,
6698 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006699 return NULL;
6700 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006701 if (PySys_Audit("os.fork", NULL) < 0) {
6702 return NULL;
6703 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006704 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006705 pid = fork();
6706 if (pid == 0) {
6707 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006708 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006709 } else {
6710 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006711 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 }
6713 if (pid == -1)
6714 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006716}
Larry Hastings2f936352014-08-05 14:04:04 +10006717#endif /* HAVE_FORK */
6718
Guido van Rossum85e3b011991-06-03 12:42:10 +00006719
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006720#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006721#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006722/*[clinic input]
6723os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006724
Larry Hastings2f936352014-08-05 14:04:04 +10006725 policy: int
6726
6727Get the maximum scheduling priority for policy.
6728[clinic start generated code]*/
6729
Larry Hastings2f936352014-08-05 14:04:04 +10006730static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006731os_sched_get_priority_max_impl(PyObject *module, int policy)
6732/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006733{
6734 int max;
6735
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006736 max = sched_get_priority_max(policy);
6737 if (max < 0)
6738 return posix_error();
6739 return PyLong_FromLong(max);
6740}
6741
Larry Hastings2f936352014-08-05 14:04:04 +10006742
6743/*[clinic input]
6744os.sched_get_priority_min
6745
6746 policy: int
6747
6748Get the minimum scheduling priority for policy.
6749[clinic start generated code]*/
6750
Larry Hastings2f936352014-08-05 14:04:04 +10006751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006752os_sched_get_priority_min_impl(PyObject *module, int policy)
6753/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006754{
6755 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006756 if (min < 0)
6757 return posix_error();
6758 return PyLong_FromLong(min);
6759}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006760#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6761
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006762
Larry Hastings2f936352014-08-05 14:04:04 +10006763#ifdef HAVE_SCHED_SETSCHEDULER
6764/*[clinic input]
6765os.sched_getscheduler
6766 pid: pid_t
6767 /
6768
Min ho Kimc4cacc82019-07-31 08:16:13 +10006769Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006770
6771Passing 0 for pid returns the scheduling policy for the calling process.
6772[clinic start generated code]*/
6773
Larry Hastings2f936352014-08-05 14:04:04 +10006774static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006775os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006776/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006777{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006778 int policy;
6779
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006780 policy = sched_getscheduler(pid);
6781 if (policy < 0)
6782 return posix_error();
6783 return PyLong_FromLong(policy);
6784}
Larry Hastings2f936352014-08-05 14:04:04 +10006785#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006786
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006787
William Orr81574b82018-10-01 22:19:56 -07006788#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006789/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006790class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006791
6792@classmethod
6793os.sched_param.__new__
6794
6795 sched_priority: object
6796 A scheduling parameter.
6797
Eddie Elizondob3966632019-11-05 07:16:14 -08006798Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006799[clinic start generated code]*/
6800
Larry Hastings2f936352014-08-05 14:04:04 +10006801static PyObject *
6802os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006803/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006804{
6805 PyObject *res;
6806
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006807 res = PyStructSequence_New(type);
6808 if (!res)
6809 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006810 Py_INCREF(sched_priority);
6811 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006812 return res;
6813}
6814
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006815PyDoc_VAR(os_sched_param__doc__);
6816
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006817static PyStructSequence_Field sched_param_fields[] = {
6818 {"sched_priority", "the scheduling priority"},
6819 {0}
6820};
6821
6822static PyStructSequence_Desc sched_param_desc = {
6823 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006824 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006825 sched_param_fields,
6826 1
6827};
6828
6829static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006830convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006831{
6832 long priority;
6833
Victor Stinner1c2fa782020-05-10 11:05:29 +02006834 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006835 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6836 return 0;
6837 }
6838 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6839 if (priority == -1 && PyErr_Occurred())
6840 return 0;
6841 if (priority > INT_MAX || priority < INT_MIN) {
6842 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6843 return 0;
6844 }
6845 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6846 return 1;
6847}
William Orr81574b82018-10-01 22:19:56 -07006848#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006849
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006850
6851#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006852/*[clinic input]
6853os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006854
Larry Hastings2f936352014-08-05 14:04:04 +10006855 pid: pid_t
6856 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006857 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006858 /
6859
6860Set the scheduling policy for the process identified by pid.
6861
6862If pid is 0, the calling process is changed.
6863param is an instance of sched_param.
6864[clinic start generated code]*/
6865
Larry Hastings2f936352014-08-05 14:04:04 +10006866static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006867os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006868 PyObject *param_obj)
6869/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006870{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006871 struct sched_param param;
6872 if (!convert_sched_param(module, param_obj, &param)) {
6873 return NULL;
6874 }
6875
Jesus Cea9c822272011-09-10 01:40:52 +02006876 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006877 ** sched_setscheduler() returns 0 in Linux, but the previous
6878 ** scheduling policy under Solaris/Illumos, and others.
6879 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006880 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006881 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006882 return posix_error();
6883 Py_RETURN_NONE;
6884}
Larry Hastings2f936352014-08-05 14:04:04 +10006885#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006886
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006887
6888#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006889/*[clinic input]
6890os.sched_getparam
6891 pid: pid_t
6892 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006893
Larry Hastings2f936352014-08-05 14:04:04 +10006894Returns scheduling parameters for the process identified by pid.
6895
6896If pid is 0, returns parameters for the calling process.
6897Return value is an instance of sched_param.
6898[clinic start generated code]*/
6899
Larry Hastings2f936352014-08-05 14:04:04 +10006900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006901os_sched_getparam_impl(PyObject *module, pid_t pid)
6902/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006903{
6904 struct sched_param param;
6905 PyObject *result;
6906 PyObject *priority;
6907
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006908 if (sched_getparam(pid, &param))
6909 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006910 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006911 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006912 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006913 return NULL;
6914 priority = PyLong_FromLong(param.sched_priority);
6915 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006916 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006917 return NULL;
6918 }
Larry Hastings2f936352014-08-05 14:04:04 +10006919 PyStructSequence_SET_ITEM(result, 0, priority);
6920 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006921}
6922
Larry Hastings2f936352014-08-05 14:04:04 +10006923
6924/*[clinic input]
6925os.sched_setparam
6926 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006927 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006928 /
6929
6930Set scheduling parameters for the process identified by pid.
6931
6932If pid is 0, sets parameters for the calling process.
6933param should be an instance of sched_param.
6934[clinic start generated code]*/
6935
Larry Hastings2f936352014-08-05 14:04:04 +10006936static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006937os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6938/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006939{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006940 struct sched_param param;
6941 if (!convert_sched_param(module, param_obj, &param)) {
6942 return NULL;
6943 }
6944
6945 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006946 return posix_error();
6947 Py_RETURN_NONE;
6948}
Larry Hastings2f936352014-08-05 14:04:04 +10006949#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006950
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006951
6952#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006953/*[clinic input]
6954os.sched_rr_get_interval -> double
6955 pid: pid_t
6956 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006957
Larry Hastings2f936352014-08-05 14:04:04 +10006958Return the round-robin quantum for the process identified by pid, in seconds.
6959
6960Value returned is a float.
6961[clinic start generated code]*/
6962
Larry Hastings2f936352014-08-05 14:04:04 +10006963static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006964os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6965/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006966{
6967 struct timespec interval;
6968 if (sched_rr_get_interval(pid, &interval)) {
6969 posix_error();
6970 return -1.0;
6971 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006972#ifdef _Py_MEMORY_SANITIZER
6973 __msan_unpoison(&interval, sizeof(interval));
6974#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006975 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6976}
6977#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006978
Larry Hastings2f936352014-08-05 14:04:04 +10006979
6980/*[clinic input]
6981os.sched_yield
6982
6983Voluntarily relinquish the CPU.
6984[clinic start generated code]*/
6985
Larry Hastings2f936352014-08-05 14:04:04 +10006986static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006987os_sched_yield_impl(PyObject *module)
6988/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006989{
6990 if (sched_yield())
6991 return posix_error();
6992 Py_RETURN_NONE;
6993}
6994
Benjamin Peterson2740af82011-08-02 17:41:34 -05006995#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006996/* The minimum number of CPUs allocated in a cpu_set_t */
6997static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006998
Larry Hastings2f936352014-08-05 14:04:04 +10006999/*[clinic input]
7000os.sched_setaffinity
7001 pid: pid_t
7002 mask : object
7003 /
7004
7005Set the CPU affinity of the process identified by pid to mask.
7006
7007mask should be an iterable of integers identifying CPUs.
7008[clinic start generated code]*/
7009
Larry Hastings2f936352014-08-05 14:04:04 +10007010static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007011os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
7012/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007013{
Antoine Pitrou84869872012-08-04 16:16:35 +02007014 int ncpus;
7015 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007016 cpu_set_t *cpu_set = NULL;
7017 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007018
Larry Hastings2f936352014-08-05 14:04:04 +10007019 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02007020 if (iterator == NULL)
7021 return NULL;
7022
7023 ncpus = NCPUS_START;
7024 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10007025 cpu_set = CPU_ALLOC(ncpus);
7026 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007027 PyErr_NoMemory();
7028 goto error;
7029 }
Larry Hastings2f936352014-08-05 14:04:04 +10007030 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007031
7032 while ((item = PyIter_Next(iterator))) {
7033 long cpu;
7034 if (!PyLong_Check(item)) {
7035 PyErr_Format(PyExc_TypeError,
7036 "expected an iterator of ints, "
7037 "but iterator yielded %R",
7038 Py_TYPE(item));
7039 Py_DECREF(item);
7040 goto error;
7041 }
7042 cpu = PyLong_AsLong(item);
7043 Py_DECREF(item);
7044 if (cpu < 0) {
7045 if (!PyErr_Occurred())
7046 PyErr_SetString(PyExc_ValueError, "negative CPU number");
7047 goto error;
7048 }
7049 if (cpu > INT_MAX - 1) {
7050 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
7051 goto error;
7052 }
7053 if (cpu >= ncpus) {
7054 /* Grow CPU mask to fit the CPU number */
7055 int newncpus = ncpus;
7056 cpu_set_t *newmask;
7057 size_t newsetsize;
7058 while (newncpus <= cpu) {
7059 if (newncpus > INT_MAX / 2)
7060 newncpus = cpu + 1;
7061 else
7062 newncpus = newncpus * 2;
7063 }
7064 newmask = CPU_ALLOC(newncpus);
7065 if (newmask == NULL) {
7066 PyErr_NoMemory();
7067 goto error;
7068 }
7069 newsetsize = CPU_ALLOC_SIZE(newncpus);
7070 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10007071 memcpy(newmask, cpu_set, setsize);
7072 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007073 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007074 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02007075 ncpus = newncpus;
7076 }
Larry Hastings2f936352014-08-05 14:04:04 +10007077 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007078 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07007079 if (PyErr_Occurred()) {
7080 goto error;
7081 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007082 Py_CLEAR(iterator);
7083
Larry Hastings2f936352014-08-05 14:04:04 +10007084 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007085 posix_error();
7086 goto error;
7087 }
Larry Hastings2f936352014-08-05 14:04:04 +10007088 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007089 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02007090
7091error:
Larry Hastings2f936352014-08-05 14:04:04 +10007092 if (cpu_set)
7093 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007094 Py_XDECREF(iterator);
7095 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007096}
7097
Larry Hastings2f936352014-08-05 14:04:04 +10007098
7099/*[clinic input]
7100os.sched_getaffinity
7101 pid: pid_t
7102 /
7103
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01007104Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10007105
7106The affinity is returned as a set of CPU identifiers.
7107[clinic start generated code]*/
7108
Larry Hastings2f936352014-08-05 14:04:04 +10007109static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007110os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03007111/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007112{
Antoine Pitrou84869872012-08-04 16:16:35 +02007113 int cpu, ncpus, count;
7114 size_t setsize;
7115 cpu_set_t *mask = NULL;
7116 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007117
Antoine Pitrou84869872012-08-04 16:16:35 +02007118 ncpus = NCPUS_START;
7119 while (1) {
7120 setsize = CPU_ALLOC_SIZE(ncpus);
7121 mask = CPU_ALLOC(ncpus);
7122 if (mask == NULL)
7123 return PyErr_NoMemory();
7124 if (sched_getaffinity(pid, setsize, mask) == 0)
7125 break;
7126 CPU_FREE(mask);
7127 if (errno != EINVAL)
7128 return posix_error();
7129 if (ncpus > INT_MAX / 2) {
7130 PyErr_SetString(PyExc_OverflowError, "could not allocate "
7131 "a large enough CPU set");
7132 return NULL;
7133 }
7134 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007135 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007136
7137 res = PySet_New(NULL);
7138 if (res == NULL)
7139 goto error;
7140 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
7141 if (CPU_ISSET_S(cpu, setsize, mask)) {
7142 PyObject *cpu_num = PyLong_FromLong(cpu);
7143 --count;
7144 if (cpu_num == NULL)
7145 goto error;
7146 if (PySet_Add(res, cpu_num)) {
7147 Py_DECREF(cpu_num);
7148 goto error;
7149 }
7150 Py_DECREF(cpu_num);
7151 }
7152 }
7153 CPU_FREE(mask);
7154 return res;
7155
7156error:
7157 if (mask)
7158 CPU_FREE(mask);
7159 Py_XDECREF(res);
7160 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007161}
7162
Benjamin Peterson2740af82011-08-02 17:41:34 -05007163#endif /* HAVE_SCHED_SETAFFINITY */
7164
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007165#endif /* HAVE_SCHED_H */
7166
Larry Hastings2f936352014-08-05 14:04:04 +10007167
Neal Norwitzb59798b2003-03-21 01:43:31 +00007168/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00007169#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Victor Stinner57766632020-10-29 15:16:23 +01007170# define DEV_PTY_FILE "/dev/ptc"
7171# define HAVE_DEV_PTMX
Neal Norwitzb59798b2003-03-21 01:43:31 +00007172#else
Victor Stinner57766632020-10-29 15:16:23 +01007173# define DEV_PTY_FILE "/dev/ptmx"
Neal Norwitzb59798b2003-03-21 01:43:31 +00007174#endif
7175
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007176#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00007177#ifdef HAVE_PTY_H
7178#include <pty.h>
7179#else
7180#ifdef HAVE_LIBUTIL_H
7181#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00007182#else
7183#ifdef HAVE_UTIL_H
7184#include <util.h>
7185#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007186#endif /* HAVE_LIBUTIL_H */
7187#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00007188#ifdef HAVE_STROPTS_H
7189#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007190#endif
ngie-eign7745ec42018-02-14 11:54:28 -08007191#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007192
Larry Hastings2f936352014-08-05 14:04:04 +10007193
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007194#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10007195/*[clinic input]
7196os.openpty
7197
7198Open a pseudo-terminal.
7199
7200Return a tuple of (master_fd, slave_fd) containing open file descriptors
7201for both the master and slave ends.
7202[clinic start generated code]*/
7203
Larry Hastings2f936352014-08-05 14:04:04 +10007204static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007205os_openpty_impl(PyObject *module)
7206/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007207{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007208 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007209#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007210 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007211#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007212#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007213 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01007214#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00007215 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007216#endif
7217#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00007218
Thomas Wouters70c21a12000-07-14 14:28:33 +00007219#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007220 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007221 goto posix_error;
7222
7223 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7224 goto error;
7225 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
7226 goto error;
7227
Neal Norwitzb59798b2003-03-21 01:43:31 +00007228#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007229 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
7230 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007231 goto posix_error;
7232 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7233 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007234
Victor Stinnerdaf45552013-08-28 00:53:59 +02007235 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00007236 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01007237 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007238
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007239#else
Victor Stinner000de532013-11-25 23:19:58 +01007240 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00007241 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007242 goto posix_error;
7243
Victor Stinner8c62be82010-05-06 00:08:46 +00007244 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007245
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 /* change permission of slave */
7247 if (grantpt(master_fd) < 0) {
7248 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007249 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007250 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007251
Victor Stinner8c62be82010-05-06 00:08:46 +00007252 /* unlock slave */
7253 if (unlockpt(master_fd) < 0) {
7254 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007255 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007256 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007257
Victor Stinner8c62be82010-05-06 00:08:46 +00007258 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007259
Victor Stinner8c62be82010-05-06 00:08:46 +00007260 slave_name = ptsname(master_fd); /* get name of slave */
7261 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007262 goto posix_error;
7263
7264 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01007265 if (slave_fd == -1)
7266 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01007267
7268 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7269 goto posix_error;
7270
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02007271#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00007272 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
7273 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00007274#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00007275 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00007276#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007277#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00007278#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00007279
Victor Stinner8c62be82010-05-06 00:08:46 +00007280 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00007281
Victor Stinnerdaf45552013-08-28 00:53:59 +02007282posix_error:
7283 posix_error();
7284error:
7285 if (master_fd != -1)
7286 close(master_fd);
7287 if (slave_fd != -1)
7288 close(slave_fd);
7289 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00007290}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007291#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007292
Larry Hastings2f936352014-08-05 14:04:04 +10007293
Fred Drake8cef4cf2000-06-28 16:40:38 +00007294#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10007295/*[clinic input]
7296os.forkpty
7297
7298Fork a new process with a new pseudo-terminal as controlling tty.
7299
7300Returns a tuple of (pid, master_fd).
7301Like fork(), return pid of 0 to the child process,
7302and pid of child to the parent process.
7303To both, return fd of newly opened pseudo-terminal.
7304[clinic start generated code]*/
7305
Larry Hastings2f936352014-08-05 14:04:04 +10007306static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007307os_forkpty_impl(PyObject *module)
7308/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007309{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007310 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00007311 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00007312
Victor Stinner81a7be32020-04-14 15:14:01 +02007313 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07007314 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
7315 return NULL;
7316 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007317 if (PySys_Audit("os.forkpty", NULL) < 0) {
7318 return NULL;
7319 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007320 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00007321 pid = forkpty(&master_fd, NULL, NULL, NULL);
7322 if (pid == 0) {
7323 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007324 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00007325 } else {
7326 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007327 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00007328 }
7329 if (pid == -1)
7330 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007331 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00007332}
Larry Hastings2f936352014-08-05 14:04:04 +10007333#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007334
Ross Lagerwall7807c352011-03-17 20:20:30 +02007335
Guido van Rossumad0ee831995-03-01 10:34:45 +00007336#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007337/*[clinic input]
7338os.getegid
7339
7340Return the current process's effective group id.
7341[clinic start generated code]*/
7342
Larry Hastings2f936352014-08-05 14:04:04 +10007343static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007344os_getegid_impl(PyObject *module)
7345/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007346{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007347 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007348}
Larry Hastings2f936352014-08-05 14:04:04 +10007349#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007350
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007351
Guido van Rossumad0ee831995-03-01 10:34:45 +00007352#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007353/*[clinic input]
7354os.geteuid
7355
7356Return the current process's effective user id.
7357[clinic start generated code]*/
7358
Larry Hastings2f936352014-08-05 14:04:04 +10007359static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007360os_geteuid_impl(PyObject *module)
7361/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007362{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007363 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007364}
Larry Hastings2f936352014-08-05 14:04:04 +10007365#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007367
Guido van Rossumad0ee831995-03-01 10:34:45 +00007368#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007369/*[clinic input]
7370os.getgid
7371
7372Return the current process's group id.
7373[clinic start generated code]*/
7374
Larry Hastings2f936352014-08-05 14:04:04 +10007375static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007376os_getgid_impl(PyObject *module)
7377/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007378{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007379 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007380}
Larry Hastings2f936352014-08-05 14:04:04 +10007381#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007382
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007383
Berker Peksag39404992016-09-15 20:45:16 +03007384#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10007385/*[clinic input]
7386os.getpid
7387
7388Return the current process id.
7389[clinic start generated code]*/
7390
Larry Hastings2f936352014-08-05 14:04:04 +10007391static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007392os_getpid_impl(PyObject *module)
7393/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007394{
Victor Stinner8c62be82010-05-06 00:08:46 +00007395 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00007396}
Berker Peksag39404992016-09-15 20:45:16 +03007397#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007398
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007399#ifdef NGROUPS_MAX
7400#define MAX_GROUPS NGROUPS_MAX
7401#else
7402 /* defined to be 16 on Solaris7, so this should be a small number */
7403#define MAX_GROUPS 64
7404#endif
7405
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007406#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10007407
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007408#ifdef __APPLE__
7409/*[clinic input]
7410os.getgrouplist
7411
7412 user: str
7413 username to lookup
7414 group as basegid: int
7415 base group id of the user
7416 /
7417
7418Returns a list of groups to which a user belongs.
7419[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007420
7421static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007422os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
7423/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
7424#else
7425/*[clinic input]
7426os.getgrouplist
7427
7428 user: str
7429 username to lookup
7430 group as basegid: gid_t
7431 base group id of the user
7432 /
7433
7434Returns a list of groups to which a user belongs.
7435[clinic start generated code]*/
7436
7437static PyObject *
7438os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
7439/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
7440#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007441{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007442 int i, ngroups;
7443 PyObject *list;
7444#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007445 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007446#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007447 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007448#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007449
7450 /*
7451 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7452 * number of supplimental groups a users can belong to.
7453 * We have to increment it by one because
7454 * getgrouplist() returns both the supplemental groups
7455 * and the primary group, i.e. all of the groups the
7456 * user belongs to.
7457 */
7458 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007459
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007460 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007461#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007462 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007463#else
7464 groups = PyMem_New(gid_t, ngroups);
7465#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007466 if (groups == NULL) {
7467 return PyErr_NoMemory();
7468 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007469
7470 int old_ngroups = ngroups;
7471 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7472 /* Success */
7473 break;
7474 }
7475
7476 /* getgrouplist() fails if the group list is too small */
7477 PyMem_Free(groups);
7478
7479 if (ngroups > old_ngroups) {
7480 /* If the group list is too small, the glibc implementation of
7481 getgrouplist() sets ngroups to the total number of groups and
7482 returns -1. */
7483 }
7484 else {
7485 /* Double the group list size */
7486 if (ngroups > INT_MAX / 2) {
7487 return PyErr_NoMemory();
7488 }
7489 ngroups *= 2;
7490 }
7491
7492 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007493 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007494
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007495#ifdef _Py_MEMORY_SANITIZER
7496 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7497 __msan_unpoison(&ngroups, sizeof(ngroups));
7498 __msan_unpoison(groups, ngroups*sizeof(*groups));
7499#endif
7500
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007501 list = PyList_New(ngroups);
7502 if (list == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01007503 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007504 return NULL;
7505 }
7506
7507 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007508#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007509 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007510#else
7511 PyObject *o = _PyLong_FromGid(groups[i]);
7512#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007513 if (o == NULL) {
7514 Py_DECREF(list);
Victor Stinner00d7abd2020-12-01 09:56:42 +01007515 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007516 return NULL;
7517 }
7518 PyList_SET_ITEM(list, i, o);
7519 }
7520
Victor Stinner00d7abd2020-12-01 09:56:42 +01007521 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007522
7523 return list;
7524}
Larry Hastings2f936352014-08-05 14:04:04 +10007525#endif /* HAVE_GETGROUPLIST */
7526
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007527
Fred Drakec9680921999-12-13 16:37:25 +00007528#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007529/*[clinic input]
7530os.getgroups
7531
7532Return list of supplemental group IDs for the process.
7533[clinic start generated code]*/
7534
Larry Hastings2f936352014-08-05 14:04:04 +10007535static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007536os_getgroups_impl(PyObject *module)
7537/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007538{
7539 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007540 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007541
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007542 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007543 * This is a helper variable to store the intermediate result when
7544 * that happens.
7545 *
7546 * To keep the code readable the OSX behaviour is unconditional,
7547 * according to the POSIX spec this should be safe on all unix-y
7548 * systems.
7549 */
7550 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007551 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007552
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007553#ifdef __APPLE__
7554 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7555 * there are more groups than can fit in grouplist. Therefore, on OS X
7556 * always first call getgroups with length 0 to get the actual number
7557 * of groups.
7558 */
7559 n = getgroups(0, NULL);
7560 if (n < 0) {
7561 return posix_error();
7562 } else if (n <= MAX_GROUPS) {
7563 /* groups will fit in existing array */
7564 alt_grouplist = grouplist;
7565 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007566 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007567 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007568 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007569 }
7570 }
7571
7572 n = getgroups(n, alt_grouplist);
7573 if (n == -1) {
7574 if (alt_grouplist != grouplist) {
7575 PyMem_Free(alt_grouplist);
7576 }
7577 return posix_error();
7578 }
7579#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007580 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007581 if (n < 0) {
7582 if (errno == EINVAL) {
7583 n = getgroups(0, NULL);
7584 if (n == -1) {
7585 return posix_error();
7586 }
7587 if (n == 0) {
7588 /* Avoid malloc(0) */
7589 alt_grouplist = grouplist;
7590 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007591 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007592 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007593 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007594 }
7595 n = getgroups(n, alt_grouplist);
7596 if (n == -1) {
7597 PyMem_Free(alt_grouplist);
7598 return posix_error();
7599 }
7600 }
7601 } else {
7602 return posix_error();
7603 }
7604 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007605#endif
7606
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007607 result = PyList_New(n);
7608 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 int i;
7610 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007611 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007612 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007613 Py_DECREF(result);
7614 result = NULL;
7615 break;
Fred Drakec9680921999-12-13 16:37:25 +00007616 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007617 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007618 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007619 }
7620
7621 if (alt_grouplist != grouplist) {
7622 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007623 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007624
Fred Drakec9680921999-12-13 16:37:25 +00007625 return result;
7626}
Larry Hastings2f936352014-08-05 14:04:04 +10007627#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007628
Antoine Pitroub7572f02009-12-02 20:46:48 +00007629#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007630#ifdef __APPLE__
7631/*[clinic input]
7632os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007633
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007634 username as oname: FSConverter
7635 gid: int
7636 /
7637
7638Initialize the group access list.
7639
7640Call the system initgroups() to initialize the group access list with all of
7641the groups of which the specified username is a member, plus the specified
7642group id.
7643[clinic start generated code]*/
7644
Antoine Pitroub7572f02009-12-02 20:46:48 +00007645static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007646os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7647/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7648#else
7649/*[clinic input]
7650os.initgroups
7651
7652 username as oname: FSConverter
7653 gid: gid_t
7654 /
7655
7656Initialize the group access list.
7657
7658Call the system initgroups() to initialize the group access list with all of
7659the groups of which the specified username is a member, plus the specified
7660group id.
7661[clinic start generated code]*/
7662
7663static PyObject *
7664os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7665/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7666#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007667{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007668 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007669
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007670 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007671 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007672
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007673 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007674}
Larry Hastings2f936352014-08-05 14:04:04 +10007675#endif /* HAVE_INITGROUPS */
7676
Antoine Pitroub7572f02009-12-02 20:46:48 +00007677
Martin v. Löwis606edc12002-06-13 21:09:11 +00007678#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007679/*[clinic input]
7680os.getpgid
7681
7682 pid: pid_t
7683
7684Call the system call getpgid(), and return the result.
7685[clinic start generated code]*/
7686
Larry Hastings2f936352014-08-05 14:04:04 +10007687static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007688os_getpgid_impl(PyObject *module, pid_t pid)
7689/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007690{
7691 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007692 if (pgid < 0)
7693 return posix_error();
7694 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007695}
7696#endif /* HAVE_GETPGID */
7697
7698
Guido van Rossumb6775db1994-08-01 11:34:53 +00007699#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007700/*[clinic input]
7701os.getpgrp
7702
7703Return the current process group id.
7704[clinic start generated code]*/
7705
Larry Hastings2f936352014-08-05 14:04:04 +10007706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007707os_getpgrp_impl(PyObject *module)
7708/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007709{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007710#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007712#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007713 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007714#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007715}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007716#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007718
Guido van Rossumb6775db1994-08-01 11:34:53 +00007719#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007720/*[clinic input]
7721os.setpgrp
7722
7723Make the current process the leader of its process group.
7724[clinic start generated code]*/
7725
Larry Hastings2f936352014-08-05 14:04:04 +10007726static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007727os_setpgrp_impl(PyObject *module)
7728/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007729{
Guido van Rossum64933891994-10-20 21:56:42 +00007730#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007732#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007733 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007734#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007735 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007736 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007737}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007738#endif /* HAVE_SETPGRP */
7739
Guido van Rossumad0ee831995-03-01 10:34:45 +00007740#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007741
7742#ifdef MS_WINDOWS
7743#include <tlhelp32.h>
7744
7745static PyObject*
7746win32_getppid()
7747{
7748 HANDLE snapshot;
7749 pid_t mypid;
7750 PyObject* result = NULL;
7751 BOOL have_record;
7752 PROCESSENTRY32 pe;
7753
7754 mypid = getpid(); /* This function never fails */
7755
7756 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7757 if (snapshot == INVALID_HANDLE_VALUE)
7758 return PyErr_SetFromWindowsErr(GetLastError());
7759
7760 pe.dwSize = sizeof(pe);
7761 have_record = Process32First(snapshot, &pe);
7762 while (have_record) {
7763 if (mypid == (pid_t)pe.th32ProcessID) {
7764 /* We could cache the ulong value in a static variable. */
7765 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7766 break;
7767 }
7768
7769 have_record = Process32Next(snapshot, &pe);
7770 }
7771
7772 /* If our loop exits and our pid was not found (result will be NULL)
7773 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7774 * error anyway, so let's raise it. */
7775 if (!result)
7776 result = PyErr_SetFromWindowsErr(GetLastError());
7777
7778 CloseHandle(snapshot);
7779
7780 return result;
7781}
7782#endif /*MS_WINDOWS*/
7783
Larry Hastings2f936352014-08-05 14:04:04 +10007784
7785/*[clinic input]
7786os.getppid
7787
7788Return the parent's process id.
7789
7790If the parent process has already exited, Windows machines will still
7791return its id; others systems will return the id of the 'init' process (1).
7792[clinic start generated code]*/
7793
Larry Hastings2f936352014-08-05 14:04:04 +10007794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007795os_getppid_impl(PyObject *module)
7796/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007797{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007798#ifdef MS_WINDOWS
7799 return win32_getppid();
7800#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007802#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007803}
7804#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007805
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007806
Fred Drake12c6e2d1999-12-14 21:25:03 +00007807#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007808/*[clinic input]
7809os.getlogin
7810
7811Return the actual login name.
7812[clinic start generated code]*/
7813
Larry Hastings2f936352014-08-05 14:04:04 +10007814static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007815os_getlogin_impl(PyObject *module)
7816/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007817{
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007819#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007820 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007821 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007822
7823 if (GetUserNameW(user_name, &num_chars)) {
7824 /* num_chars is the number of unicode chars plus null terminator */
7825 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007826 }
7827 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007828 result = PyErr_SetFromWindowsErr(GetLastError());
7829#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007830 char *name;
7831 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007832
Victor Stinner8c62be82010-05-06 00:08:46 +00007833 errno = 0;
7834 name = getlogin();
7835 if (name == NULL) {
7836 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007837 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007838 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007839 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 }
7841 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007842 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007843 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007844#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007845 return result;
7846}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007847#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007848
Larry Hastings2f936352014-08-05 14:04:04 +10007849
Guido van Rossumad0ee831995-03-01 10:34:45 +00007850#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007851/*[clinic input]
7852os.getuid
7853
7854Return the current process's user id.
7855[clinic start generated code]*/
7856
Larry Hastings2f936352014-08-05 14:04:04 +10007857static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007858os_getuid_impl(PyObject *module)
7859/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007860{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007861 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007862}
Larry Hastings2f936352014-08-05 14:04:04 +10007863#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007864
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007865
Brian Curtineb24d742010-04-12 17:16:38 +00007866#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007867#define HAVE_KILL
7868#endif /* MS_WINDOWS */
7869
7870#ifdef HAVE_KILL
7871/*[clinic input]
7872os.kill
7873
7874 pid: pid_t
7875 signal: Py_ssize_t
7876 /
7877
7878Kill a process with a signal.
7879[clinic start generated code]*/
7880
Larry Hastings2f936352014-08-05 14:04:04 +10007881static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007882os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7883/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007884{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007885 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7886 return NULL;
7887 }
7888#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007889 if (kill(pid, (int)signal) == -1)
7890 return posix_error();
7891 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007892#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007893 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007894 DWORD sig = (DWORD)signal;
7895 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007896 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007897
Victor Stinner8c62be82010-05-06 00:08:46 +00007898 /* Console processes which share a common console can be sent CTRL+C or
7899 CTRL+BREAK events, provided they handle said events. */
7900 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007901 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007902 err = GetLastError();
7903 PyErr_SetFromWindowsErr(err);
7904 }
7905 else
7906 Py_RETURN_NONE;
7907 }
Brian Curtineb24d742010-04-12 17:16:38 +00007908
Victor Stinner8c62be82010-05-06 00:08:46 +00007909 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7910 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007911 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007912 if (handle == NULL) {
7913 err = GetLastError();
7914 return PyErr_SetFromWindowsErr(err);
7915 }
Brian Curtineb24d742010-04-12 17:16:38 +00007916
Victor Stinner8c62be82010-05-06 00:08:46 +00007917 if (TerminateProcess(handle, sig) == 0) {
7918 err = GetLastError();
7919 result = PyErr_SetFromWindowsErr(err);
7920 } else {
7921 Py_INCREF(Py_None);
7922 result = Py_None;
7923 }
Brian Curtineb24d742010-04-12 17:16:38 +00007924
Victor Stinner8c62be82010-05-06 00:08:46 +00007925 CloseHandle(handle);
7926 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007927#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007928}
Larry Hastings2f936352014-08-05 14:04:04 +10007929#endif /* HAVE_KILL */
7930
7931
7932#ifdef HAVE_KILLPG
7933/*[clinic input]
7934os.killpg
7935
7936 pgid: pid_t
7937 signal: int
7938 /
7939
7940Kill a process group with a signal.
7941[clinic start generated code]*/
7942
Larry Hastings2f936352014-08-05 14:04:04 +10007943static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007944os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7945/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007946{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007947 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7948 return NULL;
7949 }
Larry Hastings2f936352014-08-05 14:04:04 +10007950 /* XXX some man pages make the `pgid` parameter an int, others
7951 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7952 take the same type. Moreover, pid_t is always at least as wide as
7953 int (else compilation of this module fails), which is safe. */
7954 if (killpg(pgid, signal) == -1)
7955 return posix_error();
7956 Py_RETURN_NONE;
7957}
7958#endif /* HAVE_KILLPG */
7959
Brian Curtineb24d742010-04-12 17:16:38 +00007960
Guido van Rossumc0125471996-06-28 18:55:32 +00007961#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007962#ifdef HAVE_SYS_LOCK_H
7963#include <sys/lock.h>
7964#endif
7965
Larry Hastings2f936352014-08-05 14:04:04 +10007966/*[clinic input]
7967os.plock
7968 op: int
7969 /
7970
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007971Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007972[clinic start generated code]*/
7973
Larry Hastings2f936352014-08-05 14:04:04 +10007974static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007975os_plock_impl(PyObject *module, int op)
7976/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007977{
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 if (plock(op) == -1)
7979 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007980 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007981}
Larry Hastings2f936352014-08-05 14:04:04 +10007982#endif /* HAVE_PLOCK */
7983
Guido van Rossumc0125471996-06-28 18:55:32 +00007984
Guido van Rossumb6775db1994-08-01 11:34:53 +00007985#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007986/*[clinic input]
7987os.setuid
7988
7989 uid: uid_t
7990 /
7991
7992Set the current process's user id.
7993[clinic start generated code]*/
7994
Larry Hastings2f936352014-08-05 14:04:04 +10007995static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007996os_setuid_impl(PyObject *module, uid_t uid)
7997/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007998{
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 if (setuid(uid) < 0)
8000 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008001 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008002}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008003#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008004
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008005
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008006#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10008007/*[clinic input]
8008os.seteuid
8009
8010 euid: uid_t
8011 /
8012
8013Set the current process's effective user id.
8014[clinic start generated code]*/
8015
Larry Hastings2f936352014-08-05 14:04:04 +10008016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008017os_seteuid_impl(PyObject *module, uid_t euid)
8018/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008019{
8020 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008022 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008023}
8024#endif /* HAVE_SETEUID */
8025
Larry Hastings2f936352014-08-05 14:04:04 +10008026
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008027#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10008028/*[clinic input]
8029os.setegid
8030
8031 egid: gid_t
8032 /
8033
8034Set the current process's effective group id.
8035[clinic start generated code]*/
8036
Larry Hastings2f936352014-08-05 14:04:04 +10008037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008038os_setegid_impl(PyObject *module, gid_t egid)
8039/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008040{
8041 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008042 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008043 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008044}
8045#endif /* HAVE_SETEGID */
8046
Larry Hastings2f936352014-08-05 14:04:04 +10008047
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008048#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10008049/*[clinic input]
8050os.setreuid
8051
8052 ruid: uid_t
8053 euid: uid_t
8054 /
8055
8056Set the current process's real and effective user ids.
8057[clinic start generated code]*/
8058
Larry Hastings2f936352014-08-05 14:04:04 +10008059static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008060os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
8061/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008062{
Victor Stinner8c62be82010-05-06 00:08:46 +00008063 if (setreuid(ruid, euid) < 0) {
8064 return posix_error();
8065 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008066 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00008067 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008068}
8069#endif /* HAVE_SETREUID */
8070
Larry Hastings2f936352014-08-05 14:04:04 +10008071
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008072#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10008073/*[clinic input]
8074os.setregid
8075
8076 rgid: gid_t
8077 egid: gid_t
8078 /
8079
8080Set the current process's real and effective group ids.
8081[clinic start generated code]*/
8082
Larry Hastings2f936352014-08-05 14:04:04 +10008083static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008084os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
8085/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008086{
8087 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008089 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008090}
8091#endif /* HAVE_SETREGID */
8092
Larry Hastings2f936352014-08-05 14:04:04 +10008093
Guido van Rossumb6775db1994-08-01 11:34:53 +00008094#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10008095/*[clinic input]
8096os.setgid
8097 gid: gid_t
8098 /
8099
8100Set the current process's group id.
8101[clinic start generated code]*/
8102
Larry Hastings2f936352014-08-05 14:04:04 +10008103static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008104os_setgid_impl(PyObject *module, gid_t gid)
8105/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008106{
Victor Stinner8c62be82010-05-06 00:08:46 +00008107 if (setgid(gid) < 0)
8108 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008109 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008110}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008111#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008112
Larry Hastings2f936352014-08-05 14:04:04 +10008113
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008114#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10008115/*[clinic input]
8116os.setgroups
8117
8118 groups: object
8119 /
8120
8121Set the groups of the current process to list.
8122[clinic start generated code]*/
8123
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008124static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008125os_setgroups(PyObject *module, PyObject *groups)
8126/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008127{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008128 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00008129 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00008130
Victor Stinner8c62be82010-05-06 00:08:46 +00008131 if (!PySequence_Check(groups)) {
8132 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
8133 return NULL;
8134 }
8135 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008136 if (len < 0) {
8137 return NULL;
8138 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008139 if (len > MAX_GROUPS) {
8140 PyErr_SetString(PyExc_ValueError, "too many groups");
8141 return NULL;
8142 }
8143 for(i = 0; i < len; i++) {
8144 PyObject *elem;
8145 elem = PySequence_GetItem(groups, i);
8146 if (!elem)
8147 return NULL;
8148 if (!PyLong_Check(elem)) {
8149 PyErr_SetString(PyExc_TypeError,
8150 "groups must be integers");
8151 Py_DECREF(elem);
8152 return NULL;
8153 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008154 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 Py_DECREF(elem);
8156 return NULL;
8157 }
8158 }
8159 Py_DECREF(elem);
8160 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008161
Victor Stinner8c62be82010-05-06 00:08:46 +00008162 if (setgroups(len, grouplist) < 0)
8163 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008164 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008165}
8166#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008167
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008168#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
8169static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008170wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008171{
Victor Stinner8c62be82010-05-06 00:08:46 +00008172 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08008173 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008174
Victor Stinner8c62be82010-05-06 00:08:46 +00008175 if (pid == -1)
8176 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008177
Zackery Spytz682107c2019-09-09 09:48:32 -06008178 // If wait succeeded but no child was ready to report status, ru will not
8179 // have been populated.
8180 if (pid == 0) {
8181 memset(ru, 0, sizeof(*ru));
8182 }
8183
Eddie Elizondob3966632019-11-05 07:16:14 -08008184 PyObject *m = PyImport_ImportModuleNoBlock("resource");
8185 if (m == NULL)
8186 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02008187 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08008188 Py_DECREF(m);
8189 if (struct_rusage == NULL)
8190 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008191
Victor Stinner8c62be82010-05-06 00:08:46 +00008192 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
8193 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08008194 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00008195 if (!result)
8196 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008197
8198#ifndef doubletime
8199#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
8200#endif
8201
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008203 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00008204 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008205 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008206#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00008207 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
8208 SET_INT(result, 2, ru->ru_maxrss);
8209 SET_INT(result, 3, ru->ru_ixrss);
8210 SET_INT(result, 4, ru->ru_idrss);
8211 SET_INT(result, 5, ru->ru_isrss);
8212 SET_INT(result, 6, ru->ru_minflt);
8213 SET_INT(result, 7, ru->ru_majflt);
8214 SET_INT(result, 8, ru->ru_nswap);
8215 SET_INT(result, 9, ru->ru_inblock);
8216 SET_INT(result, 10, ru->ru_oublock);
8217 SET_INT(result, 11, ru->ru_msgsnd);
8218 SET_INT(result, 12, ru->ru_msgrcv);
8219 SET_INT(result, 13, ru->ru_nsignals);
8220 SET_INT(result, 14, ru->ru_nvcsw);
8221 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008222#undef SET_INT
8223
Victor Stinner8c62be82010-05-06 00:08:46 +00008224 if (PyErr_Occurred()) {
8225 Py_DECREF(result);
8226 return NULL;
8227 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008228
Victor Stinner8c62be82010-05-06 00:08:46 +00008229 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008230}
8231#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
8232
Larry Hastings2f936352014-08-05 14:04:04 +10008233
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008234#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10008235/*[clinic input]
8236os.wait3
8237
8238 options: int
8239Wait for completion of a child process.
8240
8241Returns a tuple of information about the child process:
8242 (pid, status, rusage)
8243[clinic start generated code]*/
8244
Larry Hastings2f936352014-08-05 14:04:04 +10008245static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008246os_wait3_impl(PyObject *module, int options)
8247/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008248{
Victor Stinner8c62be82010-05-06 00:08:46 +00008249 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008250 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008251 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008252 WAIT_TYPE status;
8253 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008254
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008255 do {
8256 Py_BEGIN_ALLOW_THREADS
8257 pid = wait3(&status, options, &ru);
8258 Py_END_ALLOW_THREADS
8259 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8260 if (pid < 0)
8261 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008262
Victor Stinner1c2fa782020-05-10 11:05:29 +02008263 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008264}
8265#endif /* HAVE_WAIT3 */
8266
Larry Hastings2f936352014-08-05 14:04:04 +10008267
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008268#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10008269/*[clinic input]
8270
8271os.wait4
8272
8273 pid: pid_t
8274 options: int
8275
8276Wait for completion of a specific child process.
8277
8278Returns a tuple of information about the child process:
8279 (pid, status, rusage)
8280[clinic start generated code]*/
8281
Larry Hastings2f936352014-08-05 14:04:04 +10008282static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008283os_wait4_impl(PyObject *module, pid_t pid, int options)
8284/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008285{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008286 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008287 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008288 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008289 WAIT_TYPE status;
8290 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008291
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008292 do {
8293 Py_BEGIN_ALLOW_THREADS
8294 res = wait4(pid, &status, options, &ru);
8295 Py_END_ALLOW_THREADS
8296 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8297 if (res < 0)
8298 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008299
Victor Stinner1c2fa782020-05-10 11:05:29 +02008300 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008301}
8302#endif /* HAVE_WAIT4 */
8303
Larry Hastings2f936352014-08-05 14:04:04 +10008304
Ross Lagerwall7807c352011-03-17 20:20:30 +02008305#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10008306/*[clinic input]
8307os.waitid
8308
8309 idtype: idtype_t
8310 Must be one of be P_PID, P_PGID or P_ALL.
8311 id: id_t
8312 The id to wait on.
8313 options: int
8314 Constructed from the ORing of one or more of WEXITED, WSTOPPED
8315 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
8316 /
8317
8318Returns the result of waiting for a process or processes.
8319
8320Returns either waitid_result or None if WNOHANG is specified and there are
8321no children in a waitable state.
8322[clinic start generated code]*/
8323
Larry Hastings2f936352014-08-05 14:04:04 +10008324static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008325os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
8326/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008327{
8328 PyObject *result;
8329 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008330 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008331 siginfo_t si;
8332 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008333
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008334 do {
8335 Py_BEGIN_ALLOW_THREADS
8336 res = waitid(idtype, id, &si, options);
8337 Py_END_ALLOW_THREADS
8338 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8339 if (res < 0)
8340 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008341
8342 if (si.si_pid == 0)
8343 Py_RETURN_NONE;
8344
Hai Shif707d942020-03-16 21:15:01 +08008345 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008346 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008347 if (!result)
8348 return NULL;
8349
8350 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008351 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008352 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
8353 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
8354 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
8355 if (PyErr_Occurred()) {
8356 Py_DECREF(result);
8357 return NULL;
8358 }
8359
8360 return result;
8361}
Larry Hastings2f936352014-08-05 14:04:04 +10008362#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008363
Larry Hastings2f936352014-08-05 14:04:04 +10008364
8365#if defined(HAVE_WAITPID)
8366/*[clinic input]
8367os.waitpid
8368 pid: pid_t
8369 options: int
8370 /
8371
8372Wait for completion of a given child process.
8373
8374Returns a tuple of information regarding the child process:
8375 (pid, status)
8376
8377The options argument is ignored on Windows.
8378[clinic start generated code]*/
8379
Larry Hastings2f936352014-08-05 14:04:04 +10008380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008381os_waitpid_impl(PyObject *module, pid_t pid, int options)
8382/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008383{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008384 pid_t res;
8385 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008386 WAIT_TYPE status;
8387 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008388
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008389 do {
8390 Py_BEGIN_ALLOW_THREADS
8391 res = waitpid(pid, &status, options);
8392 Py_END_ALLOW_THREADS
8393 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8394 if (res < 0)
8395 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008396
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008397 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00008398}
Tim Petersab034fa2002-02-01 11:27:43 +00008399#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00008400/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10008401/*[clinic input]
8402os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07008403 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10008404 options: int
8405 /
8406
8407Wait for completion of a given process.
8408
8409Returns a tuple of information regarding the process:
8410 (pid, status << 8)
8411
8412The options argument is ignored on Windows.
8413[clinic start generated code]*/
8414
Larry Hastings2f936352014-08-05 14:04:04 +10008415static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07008416os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07008417/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008418{
8419 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07008420 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008421 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008422
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008423 do {
8424 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08008425 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008426 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08008427 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008428 Py_END_ALLOW_THREADS
8429 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008430 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008431 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008432
Victor Stinner9bee32b2020-04-22 16:30:35 +02008433 unsigned long long ustatus = (unsigned int)status;
8434
Victor Stinner8c62be82010-05-06 00:08:46 +00008435 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02008436 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00008437}
Larry Hastings2f936352014-08-05 14:04:04 +10008438#endif
8439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008440
Guido van Rossumad0ee831995-03-01 10:34:45 +00008441#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10008442/*[clinic input]
8443os.wait
8444
8445Wait for completion of a child process.
8446
8447Returns a tuple of information about the child process:
8448 (pid, status)
8449[clinic start generated code]*/
8450
Larry Hastings2f936352014-08-05 14:04:04 +10008451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008452os_wait_impl(PyObject *module)
8453/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008454{
Victor Stinner8c62be82010-05-06 00:08:46 +00008455 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008456 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008457 WAIT_TYPE status;
8458 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008459
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008460 do {
8461 Py_BEGIN_ALLOW_THREADS
8462 pid = wait(&status);
8463 Py_END_ALLOW_THREADS
8464 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8465 if (pid < 0)
8466 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008467
Victor Stinner8c62be82010-05-06 00:08:46 +00008468 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008469}
Larry Hastings2f936352014-08-05 14:04:04 +10008470#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008471
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008472#if defined(__linux__) && defined(__NR_pidfd_open)
8473/*[clinic input]
8474os.pidfd_open
8475 pid: pid_t
8476 flags: unsigned_int = 0
8477
8478Return a file descriptor referring to the process *pid*.
8479
8480The descriptor can be used to perform process management without races and
8481signals.
8482[clinic start generated code]*/
8483
8484static PyObject *
8485os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8486/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8487{
8488 int fd = syscall(__NR_pidfd_open, pid, flags);
8489 if (fd < 0) {
8490 return posix_error();
8491 }
8492 return PyLong_FromLong(fd);
8493}
8494#endif
8495
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008496
Larry Hastings9cf065c2012-06-22 16:30:09 -07008497#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008498/*[clinic input]
8499os.readlink
8500
8501 path: path_t
8502 *
8503 dir_fd: dir_fd(requires='readlinkat') = None
8504
8505Return a string representing the path to which the symbolic link points.
8506
8507If dir_fd is not None, it should be a file descriptor open to a directory,
8508and path should be relative; path will then be relative to that directory.
8509
8510dir_fd may not be implemented on your platform. If it is unavailable,
8511using it will raise a NotImplementedError.
8512[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008513
Barry Warsaw53699e91996-12-10 23:23:01 +00008514static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008515os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8516/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008517{
Berker Peksage0b5b202018-08-15 13:03:41 +03008518#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008519 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008520 ssize_t length;
Ronald Oussoren41761932020-11-08 10:05:27 +01008521#ifdef HAVE_READLINKAT
8522 int readlinkat_unavailable = 0;
8523#endif
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008524
8525 Py_BEGIN_ALLOW_THREADS
8526#ifdef HAVE_READLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01008527 if (dir_fd != DEFAULT_DIR_FD) {
8528 if (HAVE_READLINKAT_RUNTIME) {
8529 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8530 } else {
8531 readlinkat_unavailable = 1;
8532 }
8533 } else
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008534#endif
8535 length = readlink(path->narrow, buffer, MAXPATHLEN);
8536 Py_END_ALLOW_THREADS
8537
Ronald Oussoren41761932020-11-08 10:05:27 +01008538#ifdef HAVE_READLINKAT
8539 if (readlinkat_unavailable) {
8540 argument_unavailable_error(NULL, "dir_fd");
8541 return NULL;
8542 }
8543#endif
8544
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008545 if (length < 0) {
8546 return path_error(path);
8547 }
8548 buffer[length] = '\0';
8549
8550 if (PyUnicode_Check(path->object))
8551 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8552 else
8553 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008554#elif defined(MS_WINDOWS)
8555 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008556 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008557 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008558 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8559 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008560 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008561
Larry Hastings2f936352014-08-05 14:04:04 +10008562 /* First get a handle to the reparse point */
8563 Py_BEGIN_ALLOW_THREADS
8564 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008565 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008566 0,
8567 0,
8568 0,
8569 OPEN_EXISTING,
8570 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8571 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008572 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8573 /* New call DeviceIoControl to read the reparse point */
8574 io_result = DeviceIoControl(
8575 reparse_point_handle,
8576 FSCTL_GET_REPARSE_POINT,
8577 0, 0, /* in buffer */
8578 target_buffer, sizeof(target_buffer),
8579 &n_bytes_returned,
8580 0 /* we're not using OVERLAPPED_IO */
8581 );
8582 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008583 }
Larry Hastings2f936352014-08-05 14:04:04 +10008584 Py_END_ALLOW_THREADS
8585
Berker Peksage0b5b202018-08-15 13:03:41 +03008586 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008587 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008588 }
Larry Hastings2f936352014-08-05 14:04:04 +10008589
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008590 wchar_t *name = NULL;
8591 Py_ssize_t nameLen = 0;
8592 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008593 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008594 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8595 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8596 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008597 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008598 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8599 {
8600 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8601 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8602 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8603 }
8604 else
8605 {
8606 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8607 }
8608 if (name) {
8609 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8610 /* Our buffer is mutable, so this is okay */
8611 name[1] = L'\\';
8612 }
8613 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008614 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008615 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8616 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008617 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008618 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008619#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008620}
Berker Peksage0b5b202018-08-15 13:03:41 +03008621#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008622
Larry Hastings9cf065c2012-06-22 16:30:09 -07008623#if defined(MS_WINDOWS)
8624
Steve Dower6921e732018-03-05 14:26:08 -08008625/* Remove the last portion of the path - return 0 on success */
8626static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008627_dirnameW(WCHAR *path)
8628{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008629 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008630 size_t length = wcsnlen_s(path, MAX_PATH);
8631 if (length == MAX_PATH) {
8632 return -1;
8633 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008634
8635 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008636 for(ptr = path + length; ptr != path; ptr--) {
8637 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008638 break;
Steve Dower6921e732018-03-05 14:26:08 -08008639 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008640 }
8641 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008642 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008643}
8644
Minmin Gong7f21c9a2020-05-18 09:17:19 -07008645#endif
8646
8647#ifdef HAVE_SYMLINK
8648
8649#if defined(MS_WINDOWS)
8650
Victor Stinner31b3b922013-06-05 01:49:17 +02008651/* Is this path absolute? */
8652static int
8653_is_absW(const WCHAR *path)
8654{
Steve Dower6921e732018-03-05 14:26:08 -08008655 return path[0] == L'\\' || path[0] == L'/' ||
8656 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008657}
8658
Steve Dower6921e732018-03-05 14:26:08 -08008659/* join root and rest with a backslash - return 0 on success */
8660static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008661_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8662{
Victor Stinner31b3b922013-06-05 01:49:17 +02008663 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008664 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008665 }
8666
Steve Dower6921e732018-03-05 14:26:08 -08008667 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8668 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008669 }
Steve Dower6921e732018-03-05 14:26:08 -08008670
8671 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8672 return -1;
8673 }
8674
8675 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008676}
8677
Victor Stinner31b3b922013-06-05 01:49:17 +02008678/* Return True if the path at src relative to dest is a directory */
8679static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008680_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008681{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008682 WIN32_FILE_ATTRIBUTE_DATA src_info;
8683 WCHAR dest_parent[MAX_PATH];
8684 WCHAR src_resolved[MAX_PATH] = L"";
8685
8686 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008687 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8688 _dirnameW(dest_parent)) {
8689 return 0;
8690 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008691 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008692 if (_joinW(src_resolved, dest_parent, src)) {
8693 return 0;
8694 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008695 return (
8696 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8697 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8698 );
8699}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008700#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008701
Larry Hastings2f936352014-08-05 14:04:04 +10008702
8703/*[clinic input]
8704os.symlink
8705 src: path_t
8706 dst: path_t
8707 target_is_directory: bool = False
8708 *
8709 dir_fd: dir_fd(requires='symlinkat')=None
8710
8711# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8712
8713Create a symbolic link pointing to src named dst.
8714
8715target_is_directory is required on Windows if the target is to be
8716 interpreted as a directory. (On Windows, symlink requires
8717 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8718 target_is_directory is ignored on non-Windows platforms.
8719
8720If dir_fd is not None, it should be a file descriptor open to a directory,
8721 and path should be relative; path will then be relative to that directory.
8722dir_fd may not be implemented on your platform.
8723 If it is unavailable, using it will raise a NotImplementedError.
8724
8725[clinic start generated code]*/
8726
Larry Hastings2f936352014-08-05 14:04:04 +10008727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008728os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008729 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008730/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008731{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008732#ifdef MS_WINDOWS
8733 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008734 DWORD flags = 0;
8735
8736 /* Assumed true, set to false if detected to not be available. */
8737 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008738#else
8739 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01008740#ifdef HAVE_SYMLINKAT
8741 int symlinkat_unavailable = 0;
8742#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07008743#endif
8744
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008745 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8746 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8747 return NULL;
8748 }
8749
Larry Hastings9cf065c2012-06-22 16:30:09 -07008750#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008751
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008752 if (windows_has_symlink_unprivileged_flag) {
8753 /* Allow non-admin symlinks if system allows it. */
8754 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8755 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008756
Larry Hastings9cf065c2012-06-22 16:30:09 -07008757 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008758 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008759 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8760 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8761 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8762 }
8763
8764 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008765 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008766 Py_END_ALLOW_THREADS
8767
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008768 if (windows_has_symlink_unprivileged_flag && !result &&
8769 ERROR_INVALID_PARAMETER == GetLastError()) {
8770
8771 Py_BEGIN_ALLOW_THREADS
8772 _Py_BEGIN_SUPPRESS_IPH
8773 /* This error might be caused by
8774 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8775 Try again, and update windows_has_symlink_unprivileged_flag if we
8776 are successful this time.
8777
8778 NOTE: There is a risk of a race condition here if there are other
8779 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8780 another process (or thread) changes that condition in between our
8781 calls to CreateSymbolicLink.
8782 */
8783 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8784 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8785 _Py_END_SUPPRESS_IPH
8786 Py_END_ALLOW_THREADS
8787
8788 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8789 windows_has_symlink_unprivileged_flag = FALSE;
8790 }
8791 }
8792
Larry Hastings2f936352014-08-05 14:04:04 +10008793 if (!result)
8794 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008795
8796#else
8797
Steve Dower6921e732018-03-05 14:26:08 -08008798 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8799 PyErr_SetString(PyExc_ValueError,
8800 "symlink: src and dst must be the same type");
8801 return NULL;
8802 }
8803
Larry Hastings9cf065c2012-06-22 16:30:09 -07008804 Py_BEGIN_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01008805#ifdef HAVE_SYMLINKAT
8806 if (dir_fd != DEFAULT_DIR_FD) {
8807 if (HAVE_SYMLINKAT_RUNTIME) {
8808 result = symlinkat(src->narrow, dir_fd, dst->narrow);
8809 } else {
8810 symlinkat_unavailable = 1;
8811 }
8812 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008813#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008814 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008815 Py_END_ALLOW_THREADS
8816
Ronald Oussoren41761932020-11-08 10:05:27 +01008817#ifdef HAVE_SYMLINKAT
8818 if (symlinkat_unavailable) {
8819 argument_unavailable_error(NULL, "dir_fd");
8820 return NULL;
8821 }
8822#endif
8823
Larry Hastings2f936352014-08-05 14:04:04 +10008824 if (result)
8825 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008826#endif
8827
Larry Hastings2f936352014-08-05 14:04:04 +10008828 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008829}
8830#endif /* HAVE_SYMLINK */
8831
Larry Hastings9cf065c2012-06-22 16:30:09 -07008832
Brian Curtind40e6f72010-07-08 21:39:08 +00008833
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008834
Larry Hastings605a62d2012-06-24 04:33:36 -07008835static PyStructSequence_Field times_result_fields[] = {
8836 {"user", "user time"},
8837 {"system", "system time"},
8838 {"children_user", "user time of children"},
8839 {"children_system", "system time of children"},
8840 {"elapsed", "elapsed time since an arbitrary point in the past"},
8841 {NULL}
8842};
8843
8844PyDoc_STRVAR(times_result__doc__,
8845"times_result: Result from os.times().\n\n\
8846This object may be accessed either as a tuple of\n\
8847 (user, system, children_user, children_system, elapsed),\n\
8848or via the attributes user, system, children_user, children_system,\n\
8849and elapsed.\n\
8850\n\
8851See os.times for more information.");
8852
8853static PyStructSequence_Desc times_result_desc = {
8854 "times_result", /* name */
8855 times_result__doc__, /* doc */
8856 times_result_fields,
8857 5
8858};
8859
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008860#ifdef MS_WINDOWS
8861#define HAVE_TIMES /* mandatory, for the method table */
8862#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008863
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008864#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008865
8866static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008867build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008868 double children_user, double children_system,
8869 double elapsed)
8870{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008871 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008872 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008873 if (value == NULL)
8874 return NULL;
8875
8876#define SET(i, field) \
8877 { \
8878 PyObject *o = PyFloat_FromDouble(field); \
8879 if (!o) { \
8880 Py_DECREF(value); \
8881 return NULL; \
8882 } \
8883 PyStructSequence_SET_ITEM(value, i, o); \
8884 } \
8885
8886 SET(0, user);
8887 SET(1, system);
8888 SET(2, children_user);
8889 SET(3, children_system);
8890 SET(4, elapsed);
8891
8892#undef SET
8893
8894 return value;
8895}
8896
Larry Hastings605a62d2012-06-24 04:33:36 -07008897
Larry Hastings2f936352014-08-05 14:04:04 +10008898#ifndef MS_WINDOWS
8899#define NEED_TICKS_PER_SECOND
8900static long ticks_per_second = -1;
8901#endif /* MS_WINDOWS */
8902
8903/*[clinic input]
8904os.times
8905
8906Return a collection containing process timing information.
8907
8908The object returned behaves like a named tuple with these fields:
8909 (utime, stime, cutime, cstime, elapsed_time)
8910All fields are floating point numbers.
8911[clinic start generated code]*/
8912
Larry Hastings2f936352014-08-05 14:04:04 +10008913static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008914os_times_impl(PyObject *module)
8915/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008916#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008917{
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 FILETIME create, exit, kernel, user;
8919 HANDLE hProc;
8920 hProc = GetCurrentProcess();
8921 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8922 /* The fields of a FILETIME structure are the hi and lo part
8923 of a 64-bit value expressed in 100 nanosecond units.
8924 1e7 is one second in such units; 1e-7 the inverse.
8925 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8926 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008927 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008928 (double)(user.dwHighDateTime*429.4967296 +
8929 user.dwLowDateTime*1e-7),
8930 (double)(kernel.dwHighDateTime*429.4967296 +
8931 kernel.dwLowDateTime*1e-7),
8932 (double)0,
8933 (double)0,
8934 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008935}
Larry Hastings2f936352014-08-05 14:04:04 +10008936#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008937{
Larry Hastings2f936352014-08-05 14:04:04 +10008938
8939
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008940 struct tms t;
8941 clock_t c;
8942 errno = 0;
8943 c = times(&t);
8944 if (c == (clock_t) -1)
8945 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008946 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008947 (double)t.tms_utime / ticks_per_second,
8948 (double)t.tms_stime / ticks_per_second,
8949 (double)t.tms_cutime / ticks_per_second,
8950 (double)t.tms_cstime / ticks_per_second,
8951 (double)c / ticks_per_second);
8952}
Larry Hastings2f936352014-08-05 14:04:04 +10008953#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008954#endif /* HAVE_TIMES */
8955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008956
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008957#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008958/*[clinic input]
8959os.getsid
8960
8961 pid: pid_t
8962 /
8963
8964Call the system call getsid(pid) and return the result.
8965[clinic start generated code]*/
8966
Larry Hastings2f936352014-08-05 14:04:04 +10008967static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008968os_getsid_impl(PyObject *module, pid_t pid)
8969/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008970{
Victor Stinner8c62be82010-05-06 00:08:46 +00008971 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008972 sid = getsid(pid);
8973 if (sid < 0)
8974 return posix_error();
8975 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008976}
8977#endif /* HAVE_GETSID */
8978
8979
Guido van Rossumb6775db1994-08-01 11:34:53 +00008980#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008981/*[clinic input]
8982os.setsid
8983
8984Call the system call setsid().
8985[clinic start generated code]*/
8986
Larry Hastings2f936352014-08-05 14:04:04 +10008987static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008988os_setsid_impl(PyObject *module)
8989/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008990{
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 if (setsid() < 0)
8992 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008993 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008994}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008995#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008996
Larry Hastings2f936352014-08-05 14:04:04 +10008997
Guido van Rossumb6775db1994-08-01 11:34:53 +00008998#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008999/*[clinic input]
9000os.setpgid
9001
9002 pid: pid_t
9003 pgrp: pid_t
9004 /
9005
9006Call the system call setpgid(pid, pgrp).
9007[clinic start generated code]*/
9008
Larry Hastings2f936352014-08-05 14:04:04 +10009009static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009010os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
9011/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009012{
Victor Stinner8c62be82010-05-06 00:08:46 +00009013 if (setpgid(pid, pgrp) < 0)
9014 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009015 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00009016}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009017#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00009018
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009019
Guido van Rossumb6775db1994-08-01 11:34:53 +00009020#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10009021/*[clinic input]
9022os.tcgetpgrp
9023
9024 fd: int
9025 /
9026
9027Return the process group associated with the terminal specified by fd.
9028[clinic start generated code]*/
9029
Larry Hastings2f936352014-08-05 14:04:04 +10009030static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009031os_tcgetpgrp_impl(PyObject *module, int fd)
9032/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009033{
9034 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00009035 if (pgid < 0)
9036 return posix_error();
9037 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00009038}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009039#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00009040
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009041
Guido van Rossumb6775db1994-08-01 11:34:53 +00009042#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10009043/*[clinic input]
9044os.tcsetpgrp
9045
9046 fd: int
9047 pgid: pid_t
9048 /
9049
9050Set the process group associated with the terminal specified by fd.
9051[clinic start generated code]*/
9052
Larry Hastings2f936352014-08-05 14:04:04 +10009053static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009054os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
9055/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009056{
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 if (tcsetpgrp(fd, pgid) < 0)
9058 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009059 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00009060}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009061#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00009062
Guido van Rossum687dd131993-05-17 08:34:16 +00009063/* Functions acting on file descriptors */
9064
Victor Stinnerdaf45552013-08-28 00:53:59 +02009065#ifdef O_CLOEXEC
9066extern int _Py_open_cloexec_works;
9067#endif
9068
Larry Hastings2f936352014-08-05 14:04:04 +10009069
9070/*[clinic input]
9071os.open -> int
9072 path: path_t
9073 flags: int
9074 mode: int = 0o777
9075 *
9076 dir_fd: dir_fd(requires='openat') = None
9077
9078# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
9079
9080Open a file for low level IO. Returns a file descriptor (integer).
9081
9082If dir_fd is not None, it should be a file descriptor open to a directory,
9083 and path should be relative; path will then be relative to that directory.
9084dir_fd may not be implemented on your platform.
9085 If it is unavailable, using it will raise a NotImplementedError.
9086[clinic start generated code]*/
9087
Larry Hastings2f936352014-08-05 14:04:04 +10009088static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009089os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
9090/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009091{
9092 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009093 int async_err = 0;
Ronald Oussoren41761932020-11-08 10:05:27 +01009094#ifdef HAVE_OPENAT
9095 int openat_unavailable = 0;
9096#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009097
Victor Stinnerdaf45552013-08-28 00:53:59 +02009098#ifdef O_CLOEXEC
9099 int *atomic_flag_works = &_Py_open_cloexec_works;
9100#elif !defined(MS_WINDOWS)
9101 int *atomic_flag_works = NULL;
9102#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00009103
Victor Stinnerdaf45552013-08-28 00:53:59 +02009104#ifdef MS_WINDOWS
9105 flags |= O_NOINHERIT;
9106#elif defined(O_CLOEXEC)
9107 flags |= O_CLOEXEC;
9108#endif
9109
Steve Dowerb82e17e2019-05-23 08:45:22 -07009110 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
9111 return -1;
9112 }
9113
Steve Dower8fc89802015-04-12 00:26:27 -04009114 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009115 do {
9116 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07009117#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009118 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009119#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07009120#ifdef HAVE_OPENAT
Ronald Oussoren41761932020-11-08 10:05:27 +01009121 if (dir_fd != DEFAULT_DIR_FD) {
9122 if (HAVE_OPENAT_RUNTIME) {
9123 fd = openat(dir_fd, path->narrow, flags, mode);
9124
9125 } else {
9126 openat_unavailable = 1;
9127 fd = -1;
9128 }
9129 } else
Steve Dower6230aaf2016-09-09 09:03:15 -07009130#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009131 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009132#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009133 Py_END_ALLOW_THREADS
9134 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009135 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00009136
Ronald Oussoren41761932020-11-08 10:05:27 +01009137#ifdef HAVE_OPENAT
9138 if (openat_unavailable) {
9139 argument_unavailable_error(NULL, "dir_fd");
9140 return -1;
9141 }
9142#endif
9143
Victor Stinnerd3ffd322015-09-15 10:11:03 +02009144 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009145 if (!async_err)
9146 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10009147 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009148 }
9149
Victor Stinnerdaf45552013-08-28 00:53:59 +02009150#ifndef MS_WINDOWS
9151 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
9152 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10009153 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009154 }
9155#endif
9156
Larry Hastings2f936352014-08-05 14:04:04 +10009157 return fd;
9158}
9159
9160
9161/*[clinic input]
9162os.close
9163
9164 fd: int
9165
9166Close a file descriptor.
9167[clinic start generated code]*/
9168
Barry Warsaw53699e91996-12-10 23:23:01 +00009169static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009170os_close_impl(PyObject *module, int fd)
9171/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009172{
Larry Hastings2f936352014-08-05 14:04:04 +10009173 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009174 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
9175 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
9176 * for more details.
9177 */
Victor Stinner8c62be82010-05-06 00:08:46 +00009178 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009179 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04009181 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009182 Py_END_ALLOW_THREADS
9183 if (res < 0)
9184 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009185 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00009186}
9187
Larry Hastings2f936352014-08-05 14:04:04 +10009188/*[clinic input]
9189os.closerange
9190
9191 fd_low: int
9192 fd_high: int
9193 /
9194
9195Closes all file descriptors in [fd_low, fd_high), ignoring errors.
9196[clinic start generated code]*/
9197
Larry Hastings2f936352014-08-05 14:04:04 +10009198static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009199os_closerange_impl(PyObject *module, int fd_low, int fd_high)
9200/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009201{
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 Py_BEGIN_ALLOW_THREADS
Kyle Evansc230fde2020-10-11 13:54:11 -05009203 _Py_closerange(fd_low, fd_high - 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00009204 Py_END_ALLOW_THREADS
9205 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00009206}
9207
9208
Larry Hastings2f936352014-08-05 14:04:04 +10009209/*[clinic input]
9210os.dup -> int
9211
9212 fd: int
9213 /
9214
9215Return a duplicate of a file descriptor.
9216[clinic start generated code]*/
9217
Larry Hastings2f936352014-08-05 14:04:04 +10009218static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009219os_dup_impl(PyObject *module, int fd)
9220/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009221{
9222 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00009223}
9224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009225
Larry Hastings2f936352014-08-05 14:04:04 +10009226/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009227os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10009228 fd: int
9229 fd2: int
9230 inheritable: bool=True
9231
9232Duplicate file descriptor.
9233[clinic start generated code]*/
9234
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009235static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009236os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009237/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009238{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01009239 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009240#if defined(HAVE_DUP3) && \
9241 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
9242 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03009243 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009244#endif
9245
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009246 if (fd < 0 || fd2 < 0) {
9247 posix_error();
9248 return -1;
9249 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009250
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009251 /* dup2() can fail with EINTR if the target FD is already open, because it
9252 * then has to be closed. See os_close_impl() for why we don't handle EINTR
9253 * upon close(), and therefore below.
9254 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02009255#ifdef MS_WINDOWS
9256 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009257 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009258 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04009259 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009260 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009261 if (res < 0) {
9262 posix_error();
9263 return -1;
9264 }
9265 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02009266
9267 /* Character files like console cannot be make non-inheritable */
9268 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9269 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009270 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009271 }
9272
9273#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
9274 Py_BEGIN_ALLOW_THREADS
9275 if (!inheritable)
9276 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
9277 else
9278 res = dup2(fd, fd2);
9279 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009280 if (res < 0) {
9281 posix_error();
9282 return -1;
9283 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009284
9285#else
9286
9287#ifdef HAVE_DUP3
9288 if (!inheritable && dup3_works != 0) {
9289 Py_BEGIN_ALLOW_THREADS
9290 res = dup3(fd, fd2, O_CLOEXEC);
9291 Py_END_ALLOW_THREADS
9292 if (res < 0) {
9293 if (dup3_works == -1)
9294 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009295 if (dup3_works) {
9296 posix_error();
9297 return -1;
9298 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009299 }
9300 }
9301
9302 if (inheritable || dup3_works == 0)
9303 {
9304#endif
9305 Py_BEGIN_ALLOW_THREADS
9306 res = dup2(fd, fd2);
9307 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009308 if (res < 0) {
9309 posix_error();
9310 return -1;
9311 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009312
9313 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9314 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009315 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009316 }
9317#ifdef HAVE_DUP3
9318 }
9319#endif
9320
9321#endif
9322
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009323 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00009324}
9325
Larry Hastings2f936352014-08-05 14:04:04 +10009326
Ross Lagerwall7807c352011-03-17 20:20:30 +02009327#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10009328/*[clinic input]
9329os.lockf
9330
9331 fd: int
9332 An open file descriptor.
9333 command: int
9334 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
9335 length: Py_off_t
9336 The number of bytes to lock, starting at the current position.
9337 /
9338
9339Apply, test or remove a POSIX lock on an open file descriptor.
9340
9341[clinic start generated code]*/
9342
Larry Hastings2f936352014-08-05 14:04:04 +10009343static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009344os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
9345/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009346{
9347 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009348
Saiyang Gou7514f4f2020-02-12 23:47:42 -08009349 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
9350 return NULL;
9351 }
9352
Ross Lagerwall7807c352011-03-17 20:20:30 +02009353 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009354 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009355 Py_END_ALLOW_THREADS
9356
9357 if (res < 0)
9358 return posix_error();
9359
9360 Py_RETURN_NONE;
9361}
Larry Hastings2f936352014-08-05 14:04:04 +10009362#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009363
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009364
Larry Hastings2f936352014-08-05 14:04:04 +10009365/*[clinic input]
9366os.lseek -> Py_off_t
9367
9368 fd: int
9369 position: Py_off_t
9370 how: int
9371 /
9372
9373Set the position of a file descriptor. Return the new position.
9374
9375Return the new cursor position in number of bytes
9376relative to the beginning of the file.
9377[clinic start generated code]*/
9378
Larry Hastings2f936352014-08-05 14:04:04 +10009379static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009380os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
9381/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009382{
9383 Py_off_t result;
9384
Guido van Rossum687dd131993-05-17 08:34:16 +00009385#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
9387 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10009388 case 0: how = SEEK_SET; break;
9389 case 1: how = SEEK_CUR; break;
9390 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009392#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009393
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009395 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02009396#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009397 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009398#else
Larry Hastings2f936352014-08-05 14:04:04 +10009399 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009400#endif
Steve Dower8fc89802015-04-12 00:26:27 -04009401 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009403 if (result < 0)
9404 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00009405
Larry Hastings2f936352014-08-05 14:04:04 +10009406 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00009407}
9408
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009409
Larry Hastings2f936352014-08-05 14:04:04 +10009410/*[clinic input]
9411os.read
9412 fd: int
9413 length: Py_ssize_t
9414 /
9415
9416Read from a file descriptor. Returns a bytes object.
9417[clinic start generated code]*/
9418
Larry Hastings2f936352014-08-05 14:04:04 +10009419static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009420os_read_impl(PyObject *module, int fd, Py_ssize_t length)
9421/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009422{
Victor Stinner8c62be82010-05-06 00:08:46 +00009423 Py_ssize_t n;
9424 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10009425
9426 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 errno = EINVAL;
9428 return posix_error();
9429 }
Larry Hastings2f936352014-08-05 14:04:04 +10009430
Victor Stinner9a0d7a72018-11-22 15:03:40 +01009431 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10009432
9433 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00009434 if (buffer == NULL)
9435 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009436
Victor Stinner66aab0c2015-03-19 22:53:20 +01009437 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
9438 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009439 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01009440 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009441 }
Larry Hastings2f936352014-08-05 14:04:04 +10009442
9443 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00009444 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10009445
Victor Stinner8c62be82010-05-06 00:08:46 +00009446 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00009447}
9448
Ross Lagerwall7807c352011-03-17 20:20:30 +02009449#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009450 || defined(__APPLE__))) \
9451 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9452 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9453static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009454iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009455{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009456 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009457
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009458 *iov = PyMem_New(struct iovec, cnt);
9459 if (*iov == NULL) {
9460 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009461 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009462 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009463
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009464 *buf = PyMem_New(Py_buffer, cnt);
9465 if (*buf == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01009466 PyMem_Free(*iov);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009467 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009468 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009469 }
9470
9471 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009472 PyObject *item = PySequence_GetItem(seq, i);
9473 if (item == NULL)
9474 goto fail;
9475 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9476 Py_DECREF(item);
9477 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009478 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009479 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009480 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009481 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009482 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009483 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009484
9485fail:
Victor Stinner00d7abd2020-12-01 09:56:42 +01009486 PyMem_Free(*iov);
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009487 for (j = 0; j < i; j++) {
9488 PyBuffer_Release(&(*buf)[j]);
9489 }
Victor Stinner00d7abd2020-12-01 09:56:42 +01009490 PyMem_Free(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009491 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009492}
9493
9494static void
9495iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9496{
9497 int i;
Victor Stinner00d7abd2020-12-01 09:56:42 +01009498 PyMem_Free(iov);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009499 for (i = 0; i < cnt; i++) {
9500 PyBuffer_Release(&buf[i]);
9501 }
Victor Stinner00d7abd2020-12-01 09:56:42 +01009502 PyMem_Free(buf);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009503}
9504#endif
9505
Larry Hastings2f936352014-08-05 14:04:04 +10009506
Ross Lagerwall7807c352011-03-17 20:20:30 +02009507#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009508/*[clinic input]
9509os.readv -> Py_ssize_t
9510
9511 fd: int
9512 buffers: object
9513 /
9514
9515Read from a file descriptor fd into an iterable of buffers.
9516
9517The buffers should be mutable buffers accepting bytes.
9518readv will transfer data into each buffer until it is full
9519and then move on to the next buffer in the sequence to hold
9520the rest of the data.
9521
9522readv returns the total number of bytes read,
9523which may be less than the total capacity of all the buffers.
9524[clinic start generated code]*/
9525
Larry Hastings2f936352014-08-05 14:04:04 +10009526static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009527os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9528/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009529{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009530 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009531 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009532 struct iovec *iov;
9533 Py_buffer *buf;
9534
Larry Hastings2f936352014-08-05 14:04:04 +10009535 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009536 PyErr_SetString(PyExc_TypeError,
9537 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009538 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009539 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009540
Larry Hastings2f936352014-08-05 14:04:04 +10009541 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009542 if (cnt < 0)
9543 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009544
9545 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9546 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009547
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009548 do {
9549 Py_BEGIN_ALLOW_THREADS
9550 n = readv(fd, iov, cnt);
9551 Py_END_ALLOW_THREADS
9552 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009553
9554 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009555 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009556 if (!async_err)
9557 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009558 return -1;
9559 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009560
Larry Hastings2f936352014-08-05 14:04:04 +10009561 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009562}
Larry Hastings2f936352014-08-05 14:04:04 +10009563#endif /* HAVE_READV */
9564
Ross Lagerwall7807c352011-03-17 20:20:30 +02009565
9566#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009567/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009568os.pread
9569
9570 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009571 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009572 offset: Py_off_t
9573 /
9574
9575Read a number of bytes from a file descriptor starting at a particular offset.
9576
9577Read length bytes from file descriptor fd, starting at offset bytes from
9578the beginning of the file. The file offset remains unchanged.
9579[clinic start generated code]*/
9580
Larry Hastings2f936352014-08-05 14:04:04 +10009581static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009582os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9583/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009584{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009585 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009586 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009587 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009588
Larry Hastings2f936352014-08-05 14:04:04 +10009589 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009590 errno = EINVAL;
9591 return posix_error();
9592 }
Larry Hastings2f936352014-08-05 14:04:04 +10009593 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009594 if (buffer == NULL)
9595 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009596
9597 do {
9598 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009599 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009600 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009601 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009602 Py_END_ALLOW_THREADS
9603 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9604
Ross Lagerwall7807c352011-03-17 20:20:30 +02009605 if (n < 0) {
9606 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009607 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009608 }
Larry Hastings2f936352014-08-05 14:04:04 +10009609 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009610 _PyBytes_Resize(&buffer, n);
9611 return buffer;
9612}
Larry Hastings2f936352014-08-05 14:04:04 +10009613#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009614
Pablo Galindo4defba32018-01-27 16:16:37 +00009615#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9616/*[clinic input]
9617os.preadv -> Py_ssize_t
9618
9619 fd: int
9620 buffers: object
9621 offset: Py_off_t
9622 flags: int = 0
9623 /
9624
9625Reads from a file descriptor into a number of mutable bytes-like objects.
9626
9627Combines the functionality of readv() and pread(). As readv(), it will
9628transfer data into each buffer until it is full and then move on to the next
9629buffer in the sequence to hold the rest of the data. Its fourth argument,
9630specifies the file offset at which the input operation is to be performed. It
9631will return the total number of bytes read (which can be less than the total
9632capacity of all the objects).
9633
9634The flags argument contains a bitwise OR of zero or more of the following flags:
9635
9636- RWF_HIPRI
9637- RWF_NOWAIT
9638
9639Using non-zero flags requires Linux 4.6 or newer.
9640[clinic start generated code]*/
9641
9642static Py_ssize_t
9643os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9644 int flags)
9645/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9646{
9647 Py_ssize_t cnt, n;
9648 int async_err = 0;
9649 struct iovec *iov;
9650 Py_buffer *buf;
9651
9652 if (!PySequence_Check(buffers)) {
9653 PyErr_SetString(PyExc_TypeError,
9654 "preadv2() arg 2 must be a sequence");
9655 return -1;
9656 }
9657
9658 cnt = PySequence_Size(buffers);
9659 if (cnt < 0) {
9660 return -1;
9661 }
9662
9663#ifndef HAVE_PREADV2
9664 if(flags != 0) {
9665 argument_unavailable_error("preadv2", "flags");
9666 return -1;
9667 }
9668#endif
9669
9670 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9671 return -1;
9672 }
9673#ifdef HAVE_PREADV2
9674 do {
9675 Py_BEGIN_ALLOW_THREADS
9676 _Py_BEGIN_SUPPRESS_IPH
9677 n = preadv2(fd, iov, cnt, offset, flags);
9678 _Py_END_SUPPRESS_IPH
9679 Py_END_ALLOW_THREADS
9680 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9681#else
9682 do {
Ronald Oussoren41761932020-11-08 10:05:27 +01009683#ifdef __APPLE__
9684/* This entire function will be removed from the module dict when the API
9685 * is not available.
9686 */
9687#pragma clang diagnostic push
9688#pragma clang diagnostic ignored "-Wunguarded-availability"
9689#pragma clang diagnostic ignored "-Wunguarded-availability-new"
9690#endif
Pablo Galindo4defba32018-01-27 16:16:37 +00009691 Py_BEGIN_ALLOW_THREADS
9692 _Py_BEGIN_SUPPRESS_IPH
9693 n = preadv(fd, iov, cnt, offset);
9694 _Py_END_SUPPRESS_IPH
9695 Py_END_ALLOW_THREADS
9696 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +01009697
9698#ifdef __APPLE__
9699#pragma clang diagnostic pop
9700#endif
9701
Pablo Galindo4defba32018-01-27 16:16:37 +00009702#endif
9703
9704 iov_cleanup(iov, buf, cnt);
9705 if (n < 0) {
9706 if (!async_err) {
9707 posix_error();
9708 }
9709 return -1;
9710 }
9711
9712 return n;
9713}
9714#endif /* HAVE_PREADV */
9715
Larry Hastings2f936352014-08-05 14:04:04 +10009716
9717/*[clinic input]
9718os.write -> Py_ssize_t
9719
9720 fd: int
9721 data: Py_buffer
9722 /
9723
9724Write a bytes object to a file descriptor.
9725[clinic start generated code]*/
9726
Larry Hastings2f936352014-08-05 14:04:04 +10009727static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009728os_write_impl(PyObject *module, int fd, Py_buffer *data)
9729/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009730{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009731 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009732}
9733
9734#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009735#ifdef __APPLE__
9736/*[clinic input]
9737os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009738
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009739 out_fd: int
9740 in_fd: int
9741 offset: Py_off_t
9742 count as sbytes: Py_off_t
9743 headers: object(c_default="NULL") = ()
9744 trailers: object(c_default="NULL") = ()
9745 flags: int = 0
9746
9747Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9748[clinic start generated code]*/
9749
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009750static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009751os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9752 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9753 int flags)
9754/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9755#elif defined(__FreeBSD__) || defined(__DragonFly__)
9756/*[clinic input]
9757os.sendfile
9758
9759 out_fd: int
9760 in_fd: int
9761 offset: Py_off_t
9762 count: Py_ssize_t
9763 headers: object(c_default="NULL") = ()
9764 trailers: object(c_default="NULL") = ()
9765 flags: int = 0
9766
9767Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9768[clinic start generated code]*/
9769
9770static PyObject *
9771os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9772 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9773 int flags)
9774/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9775#else
9776/*[clinic input]
9777os.sendfile
9778
9779 out_fd: int
9780 in_fd: int
9781 offset as offobj: object
9782 count: Py_ssize_t
9783
9784Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9785[clinic start generated code]*/
9786
9787static PyObject *
9788os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9789 Py_ssize_t count)
9790/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9791#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009792{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009793 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009794 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009795
9796#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9797#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009798 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009799#endif
9800 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009801 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009802
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009803 sf.headers = NULL;
9804 sf.trailers = NULL;
9805
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009806 if (headers != NULL) {
9807 if (!PySequence_Check(headers)) {
9808 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009809 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009810 return NULL;
9811 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009812 Py_ssize_t i = PySequence_Size(headers);
9813 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009814 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009815 if (i > INT_MAX) {
9816 PyErr_SetString(PyExc_OverflowError,
9817 "sendfile() header is too large");
9818 return NULL;
9819 }
9820 if (i > 0) {
9821 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009822 if (iov_setup(&(sf.headers), &hbuf,
9823 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009824 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009825#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009826 for (i = 0; i < sf.hdr_cnt; i++) {
9827 Py_ssize_t blen = sf.headers[i].iov_len;
9828# define OFF_T_MAX 0x7fffffffffffffff
9829 if (sbytes >= OFF_T_MAX - blen) {
9830 PyErr_SetString(PyExc_OverflowError,
9831 "sendfile() header is too large");
9832 return NULL;
9833 }
9834 sbytes += blen;
9835 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009836#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009837 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009838 }
9839 }
9840 if (trailers != NULL) {
9841 if (!PySequence_Check(trailers)) {
9842 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009843 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009844 return NULL;
9845 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009846 Py_ssize_t i = PySequence_Size(trailers);
9847 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009848 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009849 if (i > INT_MAX) {
9850 PyErr_SetString(PyExc_OverflowError,
9851 "sendfile() trailer is too large");
9852 return NULL;
9853 }
9854 if (i > 0) {
9855 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009856 if (iov_setup(&(sf.trailers), &tbuf,
9857 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009858 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009859 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009860 }
9861 }
9862
Steve Dower8fc89802015-04-12 00:26:27 -04009863 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009864 do {
9865 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009866#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009867 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009868#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009869 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009870#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009871 Py_END_ALLOW_THREADS
9872 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009873 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009874
9875 if (sf.headers != NULL)
9876 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9877 if (sf.trailers != NULL)
9878 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9879
9880 if (ret < 0) {
9881 if ((errno == EAGAIN) || (errno == EBUSY)) {
9882 if (sbytes != 0) {
9883 // some data has been sent
9884 goto done;
9885 }
9886 else {
9887 // no data has been sent; upper application is supposed
9888 // to retry on EAGAIN or EBUSY
9889 return posix_error();
9890 }
9891 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009892 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009893 }
9894 goto done;
9895
9896done:
9897 #if !defined(HAVE_LARGEFILE_SUPPORT)
9898 return Py_BuildValue("l", sbytes);
9899 #else
9900 return Py_BuildValue("L", sbytes);
9901 #endif
9902
9903#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009904#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009905 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009906 do {
9907 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009908 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009909 Py_END_ALLOW_THREADS
9910 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009911 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009912 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009913 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009914 }
9915#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009916 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009917 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009918 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009919
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009920#if defined(__sun) && defined(__SVR4)
9921 // On Solaris, sendfile raises EINVAL rather than returning 0
9922 // when the offset is equal or bigger than the in_fd size.
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009923 struct stat st;
9924
9925 do {
9926 Py_BEGIN_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009927 ret = fstat(in_fd, &st);
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009928 Py_END_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009929 } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009930 if (ret < 0)
9931 return (!async_err) ? posix_error() : NULL;
9932
9933 if (offset >= st.st_size) {
9934 return Py_BuildValue("i", 0);
9935 }
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009936
9937 // On illumos specifically sendfile() may perform a partial write but
9938 // return -1/an error (in one confirmed case the destination socket
9939 // had a 5 second timeout set and errno was EAGAIN) and it's on the client
9940 // code to check if the offset parameter was modified by sendfile().
9941 //
9942 // We need this variable to track said change.
9943 off_t original_offset = offset;
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009944#endif
9945
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009946 do {
9947 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009948 ret = sendfile(out_fd, in_fd, &offset, count);
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009949#if defined(__sun) && defined(__SVR4)
9950 // This handles illumos-specific sendfile() partial write behavior,
9951 // see a comment above for more details.
9952 if (ret < 0 && offset != original_offset) {
9953 ret = offset - original_offset;
9954 }
9955#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009956 Py_END_ALLOW_THREADS
9957 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009958 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009959 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009960 return Py_BuildValue("n", ret);
9961#endif
9962}
Larry Hastings2f936352014-08-05 14:04:04 +10009963#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009964
Larry Hastings2f936352014-08-05 14:04:04 +10009965
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009966#if defined(__APPLE__)
9967/*[clinic input]
9968os._fcopyfile
9969
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009970 in_fd: int
9971 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009972 flags: int
9973 /
9974
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009975Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009976[clinic start generated code]*/
9977
9978static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009979os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9980/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009981{
9982 int ret;
9983
9984 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009985 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009986 Py_END_ALLOW_THREADS
9987 if (ret < 0)
9988 return posix_error();
9989 Py_RETURN_NONE;
9990}
9991#endif
9992
9993
Larry Hastings2f936352014-08-05 14:04:04 +10009994/*[clinic input]
9995os.fstat
9996
9997 fd : int
9998
9999Perform a stat system call on the given file descriptor.
10000
10001Like stat(), but for an open file descriptor.
10002Equivalent to os.stat(fd).
10003[clinic start generated code]*/
10004
Larry Hastings2f936352014-08-05 14:04:04 +100010005static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010006os_fstat_impl(PyObject *module, int fd)
10007/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010008{
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 STRUCT_STAT st;
10010 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010011 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010012
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010013 do {
10014 Py_BEGIN_ALLOW_THREADS
10015 res = FSTAT(fd, &st);
10016 Py_END_ALLOW_THREADS
10017 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +000010019#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +010010020 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +000010021#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010022 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +000010023#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 }
Tim Peters5aa91602002-01-30 05:46:57 +000010025
Victor Stinner1c2fa782020-05-10 11:05:29 +020010026 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +000010027}
10028
Larry Hastings2f936352014-08-05 14:04:04 +100010029
10030/*[clinic input]
10031os.isatty -> bool
10032 fd: int
10033 /
10034
10035Return True if the fd is connected to a terminal.
10036
10037Return True if the file descriptor is an open file descriptor
10038connected to the slave end of a terminal.
10039[clinic start generated code]*/
10040
Larry Hastings2f936352014-08-05 14:04:04 +100010041static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010042os_isatty_impl(PyObject *module, int fd)
10043/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010044{
Steve Dower8fc89802015-04-12 00:26:27 -040010045 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040010046 _Py_BEGIN_SUPPRESS_IPH
10047 return_value = isatty(fd);
10048 _Py_END_SUPPRESS_IPH
10049 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100010050}
10051
10052
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010053#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +100010054/*[clinic input]
10055os.pipe
10056
10057Create a pipe.
10058
10059Returns a tuple of two file descriptors:
10060 (read_fd, write_fd)
10061[clinic start generated code]*/
10062
Larry Hastings2f936352014-08-05 14:04:04 +100010063static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010064os_pipe_impl(PyObject *module)
10065/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +000010066{
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +020010068#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010070 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010072#else
10073 int res;
10074#endif
10075
10076#ifdef MS_WINDOWS
10077 attr.nLength = sizeof(attr);
10078 attr.lpSecurityDescriptor = NULL;
10079 attr.bInheritHandle = FALSE;
10080
10081 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -080010082 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +020010083 ok = CreatePipe(&read, &write, &attr, 0);
10084 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -070010085 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
10086 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010087 if (fds[0] == -1 || fds[1] == -1) {
10088 CloseHandle(read);
10089 CloseHandle(write);
10090 ok = 0;
10091 }
10092 }
Steve Dowerc3630612016-11-19 18:41:16 -080010093 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +020010094 Py_END_ALLOW_THREADS
10095
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +010010097 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010098#else
10099
10100#ifdef HAVE_PIPE2
10101 Py_BEGIN_ALLOW_THREADS
10102 res = pipe2(fds, O_CLOEXEC);
10103 Py_END_ALLOW_THREADS
10104
10105 if (res != 0 && errno == ENOSYS)
10106 {
10107#endif
10108 Py_BEGIN_ALLOW_THREADS
10109 res = pipe(fds);
10110 Py_END_ALLOW_THREADS
10111
10112 if (res == 0) {
10113 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
10114 close(fds[0]);
10115 close(fds[1]);
10116 return NULL;
10117 }
10118 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
10119 close(fds[0]);
10120 close(fds[1]);
10121 return NULL;
10122 }
10123 }
10124#ifdef HAVE_PIPE2
10125 }
10126#endif
10127
10128 if (res != 0)
10129 return PyErr_SetFromErrno(PyExc_OSError);
10130#endif /* !MS_WINDOWS */
10131 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +000010132}
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010133#endif /* HAVE_PIPE */
10134
Larry Hastings2f936352014-08-05 14:04:04 +100010135
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010136#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +100010137/*[clinic input]
10138os.pipe2
10139
10140 flags: int
10141 /
10142
10143Create a pipe with flags set atomically.
10144
10145Returns a tuple of two file descriptors:
10146 (read_fd, write_fd)
10147
10148flags can be constructed by ORing together one or more of these values:
10149O_NONBLOCK, O_CLOEXEC.
10150[clinic start generated code]*/
10151
Larry Hastings2f936352014-08-05 14:04:04 +100010152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010153os_pipe2_impl(PyObject *module, int flags)
10154/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010155{
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010156 int fds[2];
10157 int res;
10158
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010159 res = pipe2(fds, flags);
10160 if (res != 0)
10161 return posix_error();
10162 return Py_BuildValue("(ii)", fds[0], fds[1]);
10163}
10164#endif /* HAVE_PIPE2 */
10165
Larry Hastings2f936352014-08-05 14:04:04 +100010166
Ross Lagerwall7807c352011-03-17 20:20:30 +020010167#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +100010168/*[clinic input]
10169os.writev -> Py_ssize_t
10170 fd: int
10171 buffers: object
10172 /
10173
10174Iterate over buffers, and write the contents of each to a file descriptor.
10175
10176Returns the total number of bytes written.
10177buffers must be a sequence of bytes-like objects.
10178[clinic start generated code]*/
10179
Larry Hastings2f936352014-08-05 14:04:04 +100010180static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010181os_writev_impl(PyObject *module, int fd, PyObject *buffers)
10182/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010183{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010184 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +100010185 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010186 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010187 struct iovec *iov;
10188 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +100010189
10190 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020010191 PyErr_SetString(PyExc_TypeError,
10192 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +100010193 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010194 }
Larry Hastings2f936352014-08-05 14:04:04 +100010195 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010196 if (cnt < 0)
10197 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010198
Larry Hastings2f936352014-08-05 14:04:04 +100010199 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10200 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010201 }
10202
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010203 do {
10204 Py_BEGIN_ALLOW_THREADS
10205 result = writev(fd, iov, cnt);
10206 Py_END_ALLOW_THREADS
10207 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +020010208
10209 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010210 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010211 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +010010212
Georg Brandl306336b2012-06-24 12:55:33 +020010213 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010214}
Larry Hastings2f936352014-08-05 14:04:04 +100010215#endif /* HAVE_WRITEV */
10216
10217
10218#ifdef HAVE_PWRITE
10219/*[clinic input]
10220os.pwrite -> Py_ssize_t
10221
10222 fd: int
10223 buffer: Py_buffer
10224 offset: Py_off_t
10225 /
10226
10227Write bytes to a file descriptor starting at a particular offset.
10228
10229Write buffer to fd, starting at offset bytes from the beginning of
10230the file. Returns the number of bytes writte. Does not change the
10231current file offset.
10232[clinic start generated code]*/
10233
Larry Hastings2f936352014-08-05 14:04:04 +100010234static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010235os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
10236/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010237{
10238 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010239 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010240
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010241 do {
10242 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -040010243 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010244 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -040010245 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010246 Py_END_ALLOW_THREADS
10247 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010248
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010249 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010250 posix_error();
10251 return size;
10252}
10253#endif /* HAVE_PWRITE */
10254
Pablo Galindo4defba32018-01-27 16:16:37 +000010255#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
10256/*[clinic input]
10257os.pwritev -> Py_ssize_t
10258
10259 fd: int
10260 buffers: object
10261 offset: Py_off_t
10262 flags: int = 0
10263 /
10264
10265Writes the contents of bytes-like objects to a file descriptor at a given offset.
10266
10267Combines the functionality of writev() and pwrite(). All buffers must be a sequence
10268of bytes-like objects. Buffers are processed in array order. Entire contents of first
10269buffer is written before proceeding to second, and so on. The operating system may
10270set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
10271This function writes the contents of each object to the file descriptor and returns
10272the total number of bytes written.
10273
10274The flags argument contains a bitwise OR of zero or more of the following flags:
10275
10276- RWF_DSYNC
10277- RWF_SYNC
YoSTEALTH76ef2552020-05-27 15:32:22 -060010278- RWF_APPEND
Pablo Galindo4defba32018-01-27 16:16:37 +000010279
10280Using non-zero flags requires Linux 4.7 or newer.
10281[clinic start generated code]*/
10282
10283static Py_ssize_t
10284os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
10285 int flags)
YoSTEALTH76ef2552020-05-27 15:32:22 -060010286/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/
Pablo Galindo4defba32018-01-27 16:16:37 +000010287{
10288 Py_ssize_t cnt;
10289 Py_ssize_t result;
10290 int async_err = 0;
10291 struct iovec *iov;
10292 Py_buffer *buf;
10293
10294 if (!PySequence_Check(buffers)) {
10295 PyErr_SetString(PyExc_TypeError,
10296 "pwritev() arg 2 must be a sequence");
10297 return -1;
10298 }
10299
10300 cnt = PySequence_Size(buffers);
10301 if (cnt < 0) {
10302 return -1;
10303 }
10304
10305#ifndef HAVE_PWRITEV2
10306 if(flags != 0) {
10307 argument_unavailable_error("pwritev2", "flags");
10308 return -1;
10309 }
10310#endif
10311
10312 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10313 return -1;
10314 }
10315#ifdef HAVE_PWRITEV2
10316 do {
10317 Py_BEGIN_ALLOW_THREADS
10318 _Py_BEGIN_SUPPRESS_IPH
10319 result = pwritev2(fd, iov, cnt, offset, flags);
10320 _Py_END_SUPPRESS_IPH
10321 Py_END_ALLOW_THREADS
10322 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10323#else
Ronald Oussoren41761932020-11-08 10:05:27 +010010324
10325#ifdef __APPLE__
10326/* This entire function will be removed from the module dict when the API
10327 * is not available.
10328 */
10329#pragma clang diagnostic push
10330#pragma clang diagnostic ignored "-Wunguarded-availability"
10331#pragma clang diagnostic ignored "-Wunguarded-availability-new"
10332#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000010333 do {
10334 Py_BEGIN_ALLOW_THREADS
10335 _Py_BEGIN_SUPPRESS_IPH
10336 result = pwritev(fd, iov, cnt, offset);
10337 _Py_END_SUPPRESS_IPH
10338 Py_END_ALLOW_THREADS
10339 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +010010340
10341#ifdef __APPLE__
10342#pragma clang diagnostic pop
10343#endif
10344
Pablo Galindo4defba32018-01-27 16:16:37 +000010345#endif
10346
10347 iov_cleanup(iov, buf, cnt);
10348 if (result < 0) {
10349 if (!async_err) {
10350 posix_error();
10351 }
10352 return -1;
10353 }
10354
10355 return result;
10356}
10357#endif /* HAVE_PWRITEV */
10358
Pablo Galindoaac4d032019-05-31 19:39:47 +010010359#ifdef HAVE_COPY_FILE_RANGE
10360/*[clinic input]
10361
10362os.copy_file_range
10363 src: int
10364 Source file descriptor.
10365 dst: int
10366 Destination file descriptor.
10367 count: Py_ssize_t
10368 Number of bytes to copy.
10369 offset_src: object = None
10370 Starting offset in src.
10371 offset_dst: object = None
10372 Starting offset in dst.
10373
10374Copy count bytes from one file descriptor to another.
10375
10376If offset_src is None, then src is read from the current position;
10377respectively for offset_dst.
10378[clinic start generated code]*/
10379
10380static PyObject *
10381os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10382 PyObject *offset_src, PyObject *offset_dst)
10383/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
10384{
10385 off_t offset_src_val, offset_dst_val;
10386 off_t *p_offset_src = NULL;
10387 off_t *p_offset_dst = NULL;
10388 Py_ssize_t ret;
10389 int async_err = 0;
10390 /* The flags argument is provided to allow
10391 * for future extensions and currently must be to 0. */
10392 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +000010393
10394
Pablo Galindoaac4d032019-05-31 19:39:47 +010010395 if (count < 0) {
10396 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10397 return NULL;
10398 }
10399
10400 if (offset_src != Py_None) {
10401 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10402 return NULL;
10403 }
10404 p_offset_src = &offset_src_val;
10405 }
10406
10407 if (offset_dst != Py_None) {
10408 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10409 return NULL;
10410 }
10411 p_offset_dst = &offset_dst_val;
10412 }
10413
10414 do {
10415 Py_BEGIN_ALLOW_THREADS
10416 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
10417 Py_END_ALLOW_THREADS
10418 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10419
10420 if (ret < 0) {
10421 return (!async_err) ? posix_error() : NULL;
10422 }
10423
10424 return PyLong_FromSsize_t(ret);
10425}
10426#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +100010427
Pablo Galindodedc2cd2020-12-02 17:57:18 +000010428#if (defined(HAVE_SPLICE) && !defined(_AIX))
Pablo Galindoa57b3d32020-11-17 00:00:38 +000010429/*[clinic input]
10430
10431os.splice
10432 src: int
10433 Source file descriptor.
10434 dst: int
10435 Destination file descriptor.
10436 count: Py_ssize_t
10437 Number of bytes to copy.
10438 offset_src: object = None
10439 Starting offset in src.
10440 offset_dst: object = None
10441 Starting offset in dst.
10442 flags: unsigned_int = 0
10443 Flags to modify the semantics of the call.
10444
10445Transfer count bytes from one pipe to a descriptor or vice versa.
10446
10447If offset_src is None, then src is read from the current position;
10448respectively for offset_dst. The offset associated to the file
10449descriptor that refers to a pipe must be None.
10450[clinic start generated code]*/
10451
10452static PyObject *
10453os_splice_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10454 PyObject *offset_src, PyObject *offset_dst,
10455 unsigned int flags)
10456/*[clinic end generated code: output=d0386f25a8519dc5 input=047527c66c6d2e0a]*/
10457{
10458 off_t offset_src_val, offset_dst_val;
10459 off_t *p_offset_src = NULL;
10460 off_t *p_offset_dst = NULL;
10461 Py_ssize_t ret;
10462 int async_err = 0;
10463
10464 if (count < 0) {
10465 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10466 return NULL;
10467 }
10468
10469 if (offset_src != Py_None) {
10470 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10471 return NULL;
10472 }
10473 p_offset_src = &offset_src_val;
10474 }
10475
10476 if (offset_dst != Py_None) {
10477 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10478 return NULL;
10479 }
10480 p_offset_dst = &offset_dst_val;
10481 }
10482
10483 do {
10484 Py_BEGIN_ALLOW_THREADS
10485 ret = splice(src, p_offset_src, dst, p_offset_dst, count, flags);
10486 Py_END_ALLOW_THREADS
10487 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10488
10489 if (ret < 0) {
10490 return (!async_err) ? posix_error() : NULL;
10491 }
10492
10493 return PyLong_FromSsize_t(ret);
10494}
10495#endif /* HAVE_SPLICE*/
10496
Larry Hastings2f936352014-08-05 14:04:04 +100010497#ifdef HAVE_MKFIFO
10498/*[clinic input]
10499os.mkfifo
10500
10501 path: path_t
10502 mode: int=0o666
10503 *
10504 dir_fd: dir_fd(requires='mkfifoat')=None
10505
10506Create a "fifo" (a POSIX named pipe).
10507
10508If dir_fd is not None, it should be a file descriptor open to a directory,
10509 and path should be relative; path will then be relative to that directory.
10510dir_fd may not be implemented on your platform.
10511 If it is unavailable, using it will raise a NotImplementedError.
10512[clinic start generated code]*/
10513
Larry Hastings2f936352014-08-05 14:04:04 +100010514static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010515os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
10516/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010517{
10518 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010519 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010520
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010521 do {
10522 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010523#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010524 if (dir_fd != DEFAULT_DIR_FD)
10525 result = mkfifoat(dir_fd, path->narrow, mode);
10526 else
Ross Lagerwall7807c352011-03-17 20:20:30 +020010527#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010528 result = mkfifo(path->narrow, mode);
10529 Py_END_ALLOW_THREADS
10530 } while (result != 0 && errno == EINTR &&
10531 !(async_err = PyErr_CheckSignals()));
10532 if (result != 0)
10533 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010534
10535 Py_RETURN_NONE;
10536}
10537#endif /* HAVE_MKFIFO */
10538
10539
10540#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
10541/*[clinic input]
10542os.mknod
10543
10544 path: path_t
10545 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010546 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +100010547 *
10548 dir_fd: dir_fd(requires='mknodat')=None
10549
10550Create a node in the file system.
10551
10552Create a node in the file system (file, device special file or named pipe)
10553at path. mode specifies both the permissions to use and the
10554type of node to be created, being combined (bitwise OR) with one of
10555S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
10556device defines the newly created device special file (probably using
10557os.makedev()). Otherwise device is ignored.
10558
10559If dir_fd is not None, it should be a file descriptor open to a directory,
10560 and path should be relative; path will then be relative to that directory.
10561dir_fd may not be implemented on your platform.
10562 If it is unavailable, using it will raise a NotImplementedError.
10563[clinic start generated code]*/
10564
Larry Hastings2f936352014-08-05 14:04:04 +100010565static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010566os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -040010567 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010568/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010569{
10570 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010571 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010572
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010573 do {
10574 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010575#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010576 if (dir_fd != DEFAULT_DIR_FD)
10577 result = mknodat(dir_fd, path->narrow, mode, device);
10578 else
Larry Hastings2f936352014-08-05 14:04:04 +100010579#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010580 result = mknod(path->narrow, mode, device);
10581 Py_END_ALLOW_THREADS
10582 } while (result != 0 && errno == EINTR &&
10583 !(async_err = PyErr_CheckSignals()));
10584 if (result != 0)
10585 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010586
10587 Py_RETURN_NONE;
10588}
10589#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10590
10591
10592#ifdef HAVE_DEVICE_MACROS
10593/*[clinic input]
10594os.major -> unsigned_int
10595
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010596 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010597 /
10598
10599Extracts a device major number from a raw device number.
10600[clinic start generated code]*/
10601
Larry Hastings2f936352014-08-05 14:04:04 +100010602static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010603os_major_impl(PyObject *module, dev_t device)
10604/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010605{
10606 return major(device);
10607}
10608
10609
10610/*[clinic input]
10611os.minor -> unsigned_int
10612
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010613 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010614 /
10615
10616Extracts a device minor number from a raw device number.
10617[clinic start generated code]*/
10618
Larry Hastings2f936352014-08-05 14:04:04 +100010619static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010620os_minor_impl(PyObject *module, dev_t device)
10621/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010622{
10623 return minor(device);
10624}
10625
10626
10627/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010628os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010629
10630 major: int
10631 minor: int
10632 /
10633
10634Composes a raw device number from the major and minor device numbers.
10635[clinic start generated code]*/
10636
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010637static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010638os_makedev_impl(PyObject *module, int major, int minor)
10639/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010640{
10641 return makedev(major, minor);
10642}
10643#endif /* HAVE_DEVICE_MACROS */
10644
10645
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010646#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010647/*[clinic input]
10648os.ftruncate
10649
10650 fd: int
10651 length: Py_off_t
10652 /
10653
10654Truncate a file, specified by file descriptor, to a specific length.
10655[clinic start generated code]*/
10656
Larry Hastings2f936352014-08-05 14:04:04 +100010657static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010658os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10659/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010660{
10661 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010662 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010663
Steve Dowerb82e17e2019-05-23 08:45:22 -070010664 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10665 return NULL;
10666 }
10667
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010668 do {
10669 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010670 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010671#ifdef MS_WINDOWS
10672 result = _chsize_s(fd, length);
10673#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010674 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010675#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010676 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010677 Py_END_ALLOW_THREADS
10678 } while (result != 0 && errno == EINTR &&
10679 !(async_err = PyErr_CheckSignals()));
10680 if (result != 0)
10681 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010682 Py_RETURN_NONE;
10683}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010684#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010685
10686
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010687#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010688/*[clinic input]
10689os.truncate
10690 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10691 length: Py_off_t
10692
10693Truncate a file, specified by path, to a specific length.
10694
10695On some platforms, path may also be specified as an open file descriptor.
10696 If this functionality is unavailable, using it raises an exception.
10697[clinic start generated code]*/
10698
Larry Hastings2f936352014-08-05 14:04:04 +100010699static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010700os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10701/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010702{
10703 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010704#ifdef MS_WINDOWS
10705 int fd;
10706#endif
10707
10708 if (path->fd != -1)
10709 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010710
Steve Dowerb82e17e2019-05-23 08:45:22 -070010711 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10712 return NULL;
10713 }
10714
Larry Hastings2f936352014-08-05 14:04:04 +100010715 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010716 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010717#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010718 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010719 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010720 result = -1;
10721 else {
10722 result = _chsize_s(fd, length);
10723 close(fd);
10724 if (result < 0)
10725 errno = result;
10726 }
10727#else
10728 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010729#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010730 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010731 Py_END_ALLOW_THREADS
10732 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010733 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010734
10735 Py_RETURN_NONE;
10736}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010737#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010738
Ross Lagerwall7807c352011-03-17 20:20:30 +020010739
Victor Stinnerd6b17692014-09-30 12:20:05 +020010740/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10741 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10742 defined, which is the case in Python on AIX. AIX bug report:
10743 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10744#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10745# define POSIX_FADVISE_AIX_BUG
10746#endif
10747
Victor Stinnerec39e262014-09-30 12:35:58 +020010748
Victor Stinnerd6b17692014-09-30 12:20:05 +020010749#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010750/*[clinic input]
10751os.posix_fallocate
10752
10753 fd: int
10754 offset: Py_off_t
10755 length: Py_off_t
10756 /
10757
10758Ensure a file has allocated at least a particular number of bytes on disk.
10759
10760Ensure that the file specified by fd encompasses a range of bytes
10761starting at offset bytes from the beginning and continuing for length bytes.
10762[clinic start generated code]*/
10763
Larry Hastings2f936352014-08-05 14:04:04 +100010764static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010765os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010766 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010767/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010768{
10769 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010770 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010771
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010772 do {
10773 Py_BEGIN_ALLOW_THREADS
10774 result = posix_fallocate(fd, offset, length);
10775 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010776 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10777
10778 if (result == 0)
10779 Py_RETURN_NONE;
10780
10781 if (async_err)
10782 return NULL;
10783
10784 errno = result;
10785 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010786}
Victor Stinnerec39e262014-09-30 12:35:58 +020010787#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010788
Ross Lagerwall7807c352011-03-17 20:20:30 +020010789
Victor Stinnerd6b17692014-09-30 12:20:05 +020010790#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010791/*[clinic input]
10792os.posix_fadvise
10793
10794 fd: int
10795 offset: Py_off_t
10796 length: Py_off_t
10797 advice: int
10798 /
10799
10800Announce an intention to access data in a specific pattern.
10801
10802Announce an intention to access data in a specific pattern, thus allowing
10803the kernel to make optimizations.
10804The advice applies to the region of the file specified by fd starting at
10805offset and continuing for length bytes.
10806advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10807POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10808POSIX_FADV_DONTNEED.
10809[clinic start generated code]*/
10810
Larry Hastings2f936352014-08-05 14:04:04 +100010811static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010812os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010813 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010814/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010815{
10816 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010817 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010818
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010819 do {
10820 Py_BEGIN_ALLOW_THREADS
10821 result = posix_fadvise(fd, offset, length, advice);
10822 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010823 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10824
10825 if (result == 0)
10826 Py_RETURN_NONE;
10827
10828 if (async_err)
10829 return NULL;
10830
10831 errno = result;
10832 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010833}
Victor Stinnerec39e262014-09-30 12:35:58 +020010834#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010835
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010836
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010837#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010838static PyObject*
10839win32_putenv(PyObject *name, PyObject *value)
10840{
10841 /* Search from index 1 because on Windows starting '=' is allowed for
10842 defining hidden environment variables. */
10843 if (PyUnicode_GET_LENGTH(name) == 0 ||
10844 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10845 {
10846 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10847 return NULL;
10848 }
10849 PyObject *unicode;
10850 if (value != NULL) {
10851 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10852 }
10853 else {
10854 unicode = PyUnicode_FromFormat("%U=", name);
10855 }
10856 if (unicode == NULL) {
10857 return NULL;
10858 }
10859
10860 Py_ssize_t size;
10861 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10862 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10863 Py_DECREF(unicode);
10864
10865 if (env == NULL) {
10866 return NULL;
10867 }
10868 if (size > _MAX_ENV) {
10869 PyErr_Format(PyExc_ValueError,
10870 "the environment variable is longer than %u characters",
10871 _MAX_ENV);
10872 PyMem_Free(env);
10873 return NULL;
10874 }
10875
10876 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10877 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10878 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10879
10880 Prefer _wputenv() to be compatible with C libraries using CRT
10881 variables and CRT functions using these variables (ex: getenv()). */
10882 int err = _wputenv(env);
10883 PyMem_Free(env);
10884
10885 if (err) {
10886 posix_error();
10887 return NULL;
10888 }
10889
10890 Py_RETURN_NONE;
10891}
10892#endif
10893
10894
10895#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010896/*[clinic input]
10897os.putenv
10898
10899 name: unicode
10900 value: unicode
10901 /
10902
10903Change or add an environment variable.
10904[clinic start generated code]*/
10905
Larry Hastings2f936352014-08-05 14:04:04 +100010906static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010907os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10908/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010909{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010910 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10911 return NULL;
10912 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010913 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010914}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010915#else
Larry Hastings2f936352014-08-05 14:04:04 +100010916/*[clinic input]
10917os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010918
Larry Hastings2f936352014-08-05 14:04:04 +100010919 name: FSConverter
10920 value: FSConverter
10921 /
10922
10923Change or add an environment variable.
10924[clinic start generated code]*/
10925
Larry Hastings2f936352014-08-05 14:04:04 +100010926static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010927os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10928/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010929{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010930 const char *name_string = PyBytes_AS_STRING(name);
10931 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010932
Serhiy Storchaka77703942017-06-25 07:33:01 +030010933 if (strchr(name_string, '=') != NULL) {
10934 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10935 return NULL;
10936 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010937
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010938 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10939 return NULL;
10940 }
10941
Victor Stinnerb477d192020-01-22 22:48:16 +010010942 if (setenv(name_string, value_string, 1)) {
10943 return posix_error();
10944 }
Larry Hastings2f936352014-08-05 14:04:04 +100010945 Py_RETURN_NONE;
10946}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010947#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010948
10949
Victor Stinner161e7b32020-01-24 11:53:44 +010010950#ifdef MS_WINDOWS
10951/*[clinic input]
10952os.unsetenv
10953 name: unicode
10954 /
10955
10956Delete an environment variable.
10957[clinic start generated code]*/
10958
10959static PyObject *
10960os_unsetenv_impl(PyObject *module, PyObject *name)
10961/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10962{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010963 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10964 return NULL;
10965 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010966 return win32_putenv(name, NULL);
10967}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010968#else
Larry Hastings2f936352014-08-05 14:04:04 +100010969/*[clinic input]
10970os.unsetenv
10971 name: FSConverter
10972 /
10973
10974Delete an environment variable.
10975[clinic start generated code]*/
10976
Larry Hastings2f936352014-08-05 14:04:04 +100010977static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010978os_unsetenv_impl(PyObject *module, PyObject *name)
10979/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010980{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010981 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10982 return NULL;
10983 }
Victor Stinner984890f2011-11-24 13:53:38 +010010984#ifdef HAVE_BROKEN_UNSETENV
10985 unsetenv(PyBytes_AS_STRING(name));
10986#else
Victor Stinner161e7b32020-01-24 11:53:44 +010010987 int err = unsetenv(PyBytes_AS_STRING(name));
10988 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010010989 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010010990 }
Victor Stinner984890f2011-11-24 13:53:38 +010010991#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010992
Victor Stinner84ae1182010-05-06 22:05:07 +000010993 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010994}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010995#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000010996
Larry Hastings2f936352014-08-05 14:04:04 +100010997
10998/*[clinic input]
10999os.strerror
11000
11001 code: int
11002 /
11003
11004Translate an error code to a message string.
11005[clinic start generated code]*/
11006
Larry Hastings2f936352014-08-05 14:04:04 +100011007static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011008os_strerror_impl(PyObject *module, int code)
11009/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011010{
11011 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000011012 if (message == NULL) {
11013 PyErr_SetString(PyExc_ValueError,
11014 "strerror() argument out of range");
11015 return NULL;
11016 }
Victor Stinner1b579672011-12-17 05:47:23 +010011017 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000011018}
Guido van Rossumb6a47161997-09-15 22:54:34 +000011019
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011020
Guido van Rossumc9641791998-08-04 15:26:23 +000011021#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011022#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100011023/*[clinic input]
11024os.WCOREDUMP -> bool
11025
11026 status: int
11027 /
11028
11029Return True if the process returning status was dumped to a core file.
11030[clinic start generated code]*/
11031
Larry Hastings2f936352014-08-05 14:04:04 +100011032static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011033os_WCOREDUMP_impl(PyObject *module, int status)
11034/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011035{
11036 WAIT_TYPE wait_status;
11037 WAIT_STATUS_INT(wait_status) = status;
11038 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000011039}
11040#endif /* WCOREDUMP */
11041
Larry Hastings2f936352014-08-05 14:04:04 +100011042
Fred Drake106c1a02002-04-23 15:58:02 +000011043#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100011044/*[clinic input]
11045os.WIFCONTINUED -> bool
11046
11047 status: int
11048
11049Return True if a particular process was continued from a job control stop.
11050
11051Return True if the process returning status was continued from a
11052job control stop.
11053[clinic start generated code]*/
11054
Larry Hastings2f936352014-08-05 14:04:04 +100011055static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011056os_WIFCONTINUED_impl(PyObject *module, int status)
11057/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011058{
11059 WAIT_TYPE wait_status;
11060 WAIT_STATUS_INT(wait_status) = status;
11061 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000011062}
11063#endif /* WIFCONTINUED */
11064
Larry Hastings2f936352014-08-05 14:04:04 +100011065
Guido van Rossumc9641791998-08-04 15:26:23 +000011066#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100011067/*[clinic input]
11068os.WIFSTOPPED -> bool
11069
11070 status: int
11071
11072Return True if the process returning status was stopped.
11073[clinic start generated code]*/
11074
Larry Hastings2f936352014-08-05 14:04:04 +100011075static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011076os_WIFSTOPPED_impl(PyObject *module, int status)
11077/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011078{
11079 WAIT_TYPE wait_status;
11080 WAIT_STATUS_INT(wait_status) = status;
11081 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011082}
11083#endif /* WIFSTOPPED */
11084
Larry Hastings2f936352014-08-05 14:04:04 +100011085
Guido van Rossumc9641791998-08-04 15:26:23 +000011086#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100011087/*[clinic input]
11088os.WIFSIGNALED -> bool
11089
11090 status: int
11091
11092Return True if the process returning status was terminated by a signal.
11093[clinic start generated code]*/
11094
Larry Hastings2f936352014-08-05 14:04:04 +100011095static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011096os_WIFSIGNALED_impl(PyObject *module, int status)
11097/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011098{
11099 WAIT_TYPE wait_status;
11100 WAIT_STATUS_INT(wait_status) = status;
11101 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011102}
11103#endif /* WIFSIGNALED */
11104
Larry Hastings2f936352014-08-05 14:04:04 +100011105
Guido van Rossumc9641791998-08-04 15:26:23 +000011106#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100011107/*[clinic input]
11108os.WIFEXITED -> bool
11109
11110 status: int
11111
11112Return True if the process returning status exited via the exit() system call.
11113[clinic start generated code]*/
11114
Larry Hastings2f936352014-08-05 14:04:04 +100011115static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011116os_WIFEXITED_impl(PyObject *module, int status)
11117/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011118{
11119 WAIT_TYPE wait_status;
11120 WAIT_STATUS_INT(wait_status) = status;
11121 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011122}
11123#endif /* WIFEXITED */
11124
Larry Hastings2f936352014-08-05 14:04:04 +100011125
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000011126#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100011127/*[clinic input]
11128os.WEXITSTATUS -> int
11129
11130 status: int
11131
11132Return the process return code from status.
11133[clinic start generated code]*/
11134
Larry Hastings2f936352014-08-05 14:04:04 +100011135static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011136os_WEXITSTATUS_impl(PyObject *module, int status)
11137/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011138{
11139 WAIT_TYPE wait_status;
11140 WAIT_STATUS_INT(wait_status) = status;
11141 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011142}
11143#endif /* WEXITSTATUS */
11144
Larry Hastings2f936352014-08-05 14:04:04 +100011145
Guido van Rossumc9641791998-08-04 15:26:23 +000011146#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011147/*[clinic input]
11148os.WTERMSIG -> int
11149
11150 status: int
11151
11152Return the signal that terminated the process that provided the status value.
11153[clinic start generated code]*/
11154
Larry Hastings2f936352014-08-05 14:04:04 +100011155static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011156os_WTERMSIG_impl(PyObject *module, int status)
11157/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011158{
11159 WAIT_TYPE wait_status;
11160 WAIT_STATUS_INT(wait_status) = status;
11161 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011162}
11163#endif /* WTERMSIG */
11164
Larry Hastings2f936352014-08-05 14:04:04 +100011165
Guido van Rossumc9641791998-08-04 15:26:23 +000011166#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011167/*[clinic input]
11168os.WSTOPSIG -> int
11169
11170 status: int
11171
11172Return the signal that stopped the process that provided the status value.
11173[clinic start generated code]*/
11174
Larry Hastings2f936352014-08-05 14:04:04 +100011175static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011176os_WSTOPSIG_impl(PyObject *module, int status)
11177/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011178{
11179 WAIT_TYPE wait_status;
11180 WAIT_STATUS_INT(wait_status) = status;
11181 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011182}
11183#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000011184#endif /* HAVE_SYS_WAIT_H */
11185
11186
Thomas Wouters477c8d52006-05-27 19:21:47 +000011187#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000011188#ifdef _SCO_DS
11189/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
11190 needed definitions in sys/statvfs.h */
11191#define _SVID3
11192#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011193#include <sys/statvfs.h>
11194
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011195static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020011196_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
11197 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080011198 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011199 if (v == NULL)
11200 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011201
11202#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11204 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11205 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
11206 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
11207 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
11208 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
11209 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
11210 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
11211 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11212 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011213#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11215 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11216 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011217 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000011218 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011219 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011221 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011222 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011223 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000011224 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011225 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011227 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011228 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11229 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011230#endif
Michael Felt502d5512018-01-05 13:01:58 +010011231/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
11232 * (issue #32390). */
11233#if defined(_AIX) && defined(_ALL_SOURCE)
11234 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
11235#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010011236 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010011237#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010011238 if (PyErr_Occurred()) {
11239 Py_DECREF(v);
11240 return NULL;
11241 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011242
Victor Stinner8c62be82010-05-06 00:08:46 +000011243 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011244}
11245
Larry Hastings2f936352014-08-05 14:04:04 +100011246
11247/*[clinic input]
11248os.fstatvfs
11249 fd: int
11250 /
11251
11252Perform an fstatvfs system call on the given fd.
11253
11254Equivalent to statvfs(fd).
11255[clinic start generated code]*/
11256
Larry Hastings2f936352014-08-05 14:04:04 +100011257static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011258os_fstatvfs_impl(PyObject *module, int fd)
11259/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011260{
11261 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011262 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011263 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011264
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011265 do {
11266 Py_BEGIN_ALLOW_THREADS
11267 result = fstatvfs(fd, &st);
11268 Py_END_ALLOW_THREADS
11269 } while (result != 0 && errno == EINTR &&
11270 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100011271 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011272 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011273
Victor Stinner1c2fa782020-05-10 11:05:29 +020011274 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011275}
Larry Hastings2f936352014-08-05 14:04:04 +100011276#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000011277
11278
Thomas Wouters477c8d52006-05-27 19:21:47 +000011279#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000011280#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100011281/*[clinic input]
11282os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000011283
Larry Hastings2f936352014-08-05 14:04:04 +100011284 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
11285
11286Perform a statvfs system call on the given path.
11287
11288path may always be specified as a string.
11289On some platforms, path may also be specified as an open file descriptor.
11290 If this functionality is unavailable, using it raises an exception.
11291[clinic start generated code]*/
11292
Larry Hastings2f936352014-08-05 14:04:04 +100011293static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011294os_statvfs_impl(PyObject *module, path_t *path)
11295/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011296{
11297 int result;
11298 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011299
11300 Py_BEGIN_ALLOW_THREADS
11301#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100011302 if (path->fd != -1) {
Larry Hastings2f936352014-08-05 14:04:04 +100011303 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011304 }
11305 else
11306#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011307 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011308 Py_END_ALLOW_THREADS
11309
11310 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011311 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011312 }
11313
Victor Stinner1c2fa782020-05-10 11:05:29 +020011314 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011315}
Larry Hastings2f936352014-08-05 14:04:04 +100011316#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
11317
Guido van Rossum94f6f721999-01-06 18:42:14 +000011318
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011319#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011320/*[clinic input]
11321os._getdiskusage
11322
Steve Dower23ad6d02018-02-22 10:39:10 -080011323 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100011324
11325Return disk usage statistics about the given path as a (total, free) tuple.
11326[clinic start generated code]*/
11327
Larry Hastings2f936352014-08-05 14:04:04 +100011328static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080011329os__getdiskusage_impl(PyObject *module, path_t *path)
11330/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011331{
11332 BOOL retval;
11333 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040011334 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011335
11336 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080011337 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011338 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040011339 if (retval == 0) {
11340 if (GetLastError() == ERROR_DIRECTORY) {
11341 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011342
Joe Pamerc8c02492018-09-25 10:57:36 -040011343 dir_path = PyMem_New(wchar_t, path->length + 1);
11344 if (dir_path == NULL) {
11345 return PyErr_NoMemory();
11346 }
11347
11348 wcscpy_s(dir_path, path->length + 1, path->wide);
11349
11350 if (_dirnameW(dir_path) != -1) {
11351 Py_BEGIN_ALLOW_THREADS
11352 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
11353 Py_END_ALLOW_THREADS
11354 }
11355 /* Record the last error in case it's modified by PyMem_Free. */
11356 err = GetLastError();
11357 PyMem_Free(dir_path);
11358 if (retval) {
11359 goto success;
11360 }
11361 }
11362 return PyErr_SetFromWindowsErr(err);
11363 }
11364
11365success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011366 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
11367}
Larry Hastings2f936352014-08-05 14:04:04 +100011368#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011369
11370
Fred Drakec9680921999-12-13 16:37:25 +000011371/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
11372 * It maps strings representing configuration variable names to
11373 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000011374 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000011375 * rarely-used constants. There are three separate tables that use
11376 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000011377 *
11378 * This code is always included, even if none of the interfaces that
11379 * need it are included. The #if hackery needed to avoid it would be
11380 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000011381 */
11382struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011383 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011384 int value;
Fred Drakec9680921999-12-13 16:37:25 +000011385};
11386
Fred Drake12c6e2d1999-12-14 21:25:03 +000011387static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011388conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000011389 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000011390{
Christian Heimes217cfd12007-12-02 14:31:20 +000011391 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011392 int value = _PyLong_AsInt(arg);
11393 if (value == -1 && PyErr_Occurred())
11394 return 0;
11395 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000011396 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000011397 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000011398 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000011399 /* look up the value in the table using a binary search */
11400 size_t lo = 0;
11401 size_t mid;
11402 size_t hi = tablesize;
11403 int cmp;
11404 const char *confname;
11405 if (!PyUnicode_Check(arg)) {
11406 PyErr_SetString(PyExc_TypeError,
11407 "configuration names must be strings or integers");
11408 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011409 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020011410 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000011411 if (confname == NULL)
11412 return 0;
11413 while (lo < hi) {
11414 mid = (lo + hi) / 2;
11415 cmp = strcmp(confname, table[mid].name);
11416 if (cmp < 0)
11417 hi = mid;
11418 else if (cmp > 0)
11419 lo = mid + 1;
11420 else {
11421 *valuep = table[mid].value;
11422 return 1;
11423 }
11424 }
11425 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
11426 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000011428}
11429
11430
11431#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
11432static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011433#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011434 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011435#endif
11436#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011437 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011438#endif
Fred Drakec9680921999-12-13 16:37:25 +000011439#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011440 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011441#endif
11442#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000011443 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000011444#endif
11445#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000011446 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000011447#endif
11448#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000011449 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000011450#endif
11451#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011452 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011453#endif
11454#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000011455 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000011456#endif
11457#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011458 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000011459#endif
11460#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011461 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011462#endif
11463#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011464 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000011465#endif
11466#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011467 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011468#endif
11469#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011470 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000011471#endif
11472#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011473 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011474#endif
11475#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011476 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000011477#endif
11478#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011479 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011480#endif
11481#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011482 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000011483#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000011484#ifdef _PC_ACL_ENABLED
11485 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
11486#endif
11487#ifdef _PC_MIN_HOLE_SIZE
11488 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
11489#endif
11490#ifdef _PC_ALLOC_SIZE_MIN
11491 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
11492#endif
11493#ifdef _PC_REC_INCR_XFER_SIZE
11494 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
11495#endif
11496#ifdef _PC_REC_MAX_XFER_SIZE
11497 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
11498#endif
11499#ifdef _PC_REC_MIN_XFER_SIZE
11500 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
11501#endif
11502#ifdef _PC_REC_XFER_ALIGN
11503 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
11504#endif
11505#ifdef _PC_SYMLINK_MAX
11506 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
11507#endif
11508#ifdef _PC_XATTR_ENABLED
11509 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
11510#endif
11511#ifdef _PC_XATTR_EXISTS
11512 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
11513#endif
11514#ifdef _PC_TIMESTAMP_RESOLUTION
11515 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
11516#endif
Fred Drakec9680921999-12-13 16:37:25 +000011517};
11518
Fred Drakec9680921999-12-13 16:37:25 +000011519static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011520conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011521{
11522 return conv_confname(arg, valuep, posix_constants_pathconf,
11523 sizeof(posix_constants_pathconf)
11524 / sizeof(struct constdef));
11525}
11526#endif
11527
Larry Hastings2f936352014-08-05 14:04:04 +100011528
Fred Drakec9680921999-12-13 16:37:25 +000011529#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011530/*[clinic input]
11531os.fpathconf -> long
11532
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011533 fd: fildes
Larry Hastings2f936352014-08-05 14:04:04 +100011534 name: path_confname
11535 /
11536
11537Return the configuration limit name for the file descriptor fd.
11538
11539If there is no limit, return -1.
11540[clinic start generated code]*/
11541
Larry Hastings2f936352014-08-05 14:04:04 +100011542static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011543os_fpathconf_impl(PyObject *module, int fd, int name)
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011544/*[clinic end generated code: output=d5b7042425fc3e21 input=5b8d2471cfaae186]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011545{
11546 long limit;
11547
11548 errno = 0;
11549 limit = fpathconf(fd, name);
11550 if (limit == -1 && errno != 0)
11551 posix_error();
11552
11553 return limit;
11554}
11555#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011556
11557
11558#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011559/*[clinic input]
11560os.pathconf -> long
11561 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
11562 name: path_confname
11563
11564Return the configuration limit name for the file or directory path.
11565
11566If there is no limit, return -1.
11567On some platforms, path may also be specified as an open file descriptor.
11568 If this functionality is unavailable, using it raises an exception.
11569[clinic start generated code]*/
11570
Larry Hastings2f936352014-08-05 14:04:04 +100011571static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011572os_pathconf_impl(PyObject *module, path_t *path, int name)
11573/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011574{
Victor Stinner8c62be82010-05-06 00:08:46 +000011575 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000011576
Victor Stinner8c62be82010-05-06 00:08:46 +000011577 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020011578#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011579 if (path->fd != -1)
11580 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011581 else
11582#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011583 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011584 if (limit == -1 && errno != 0) {
11585 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011586 /* could be a path or name problem */
11587 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011588 else
Larry Hastings2f936352014-08-05 14:04:04 +100011589 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011590 }
Larry Hastings2f936352014-08-05 14:04:04 +100011591
11592 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011593}
Larry Hastings2f936352014-08-05 14:04:04 +100011594#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011595
11596#ifdef HAVE_CONFSTR
11597static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011598#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011599 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011600#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011601#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011602 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011603#endif
11604#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011605 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011606#endif
Fred Draked86ed291999-12-15 15:34:33 +000011607#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011608 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011609#endif
11610#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011611 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011612#endif
11613#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011614 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011615#endif
11616#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011617 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011618#endif
Fred Drakec9680921999-12-13 16:37:25 +000011619#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011620 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011621#endif
11622#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011623 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011624#endif
11625#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011626 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011627#endif
11628#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011629 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011630#endif
11631#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011632 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011633#endif
11634#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011635 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011636#endif
11637#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011638 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011639#endif
11640#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011641 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011642#endif
Fred Draked86ed291999-12-15 15:34:33 +000011643#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011644 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011645#endif
Fred Drakec9680921999-12-13 16:37:25 +000011646#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011647 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011648#endif
Fred Draked86ed291999-12-15 15:34:33 +000011649#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011650 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011651#endif
11652#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011653 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011654#endif
11655#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011656 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011657#endif
11658#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011659 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011660#endif
Fred Drakec9680921999-12-13 16:37:25 +000011661#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011662 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011663#endif
11664#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011665 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011666#endif
11667#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011668 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011669#endif
11670#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011671 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011672#endif
11673#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011674 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011675#endif
11676#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011677 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011678#endif
11679#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011680 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011681#endif
11682#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011683 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011684#endif
11685#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011686 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011687#endif
11688#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011689 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011690#endif
11691#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011692 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011693#endif
11694#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011695 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011696#endif
11697#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011698 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011699#endif
11700#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011701 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011702#endif
11703#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011704 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011705#endif
11706#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011707 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011708#endif
Fred Draked86ed291999-12-15 15:34:33 +000011709#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011710 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011711#endif
11712#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011713 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011714#endif
11715#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011716 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011717#endif
11718#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011719 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011720#endif
11721#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011722 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011723#endif
11724#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011725 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011726#endif
11727#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011728 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011729#endif
11730#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011731 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011732#endif
11733#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011734 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011735#endif
11736#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011737 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011738#endif
11739#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011740 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011741#endif
11742#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011743 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011744#endif
11745#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011746 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011747#endif
Fred Drakec9680921999-12-13 16:37:25 +000011748};
11749
11750static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011751conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011752{
11753 return conv_confname(arg, valuep, posix_constants_confstr,
11754 sizeof(posix_constants_confstr)
11755 / sizeof(struct constdef));
11756}
11757
Larry Hastings2f936352014-08-05 14:04:04 +100011758
11759/*[clinic input]
11760os.confstr
11761
11762 name: confstr_confname
11763 /
11764
11765Return a string-valued system configuration variable.
11766[clinic start generated code]*/
11767
Larry Hastings2f936352014-08-05 14:04:04 +100011768static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011769os_confstr_impl(PyObject *module, int name)
11770/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011771{
11772 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011773 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011774 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011775
Victor Stinnercb043522010-09-10 23:49:04 +000011776 errno = 0;
11777 len = confstr(name, buffer, sizeof(buffer));
11778 if (len == 0) {
11779 if (errno) {
11780 posix_error();
11781 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011782 }
11783 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011784 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011785 }
11786 }
Victor Stinnercb043522010-09-10 23:49:04 +000011787
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011788 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011789 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011790 char *buf = PyMem_Malloc(len);
11791 if (buf == NULL)
11792 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011793 len2 = confstr(name, buf, len);
11794 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011795 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011796 PyMem_Free(buf);
11797 }
11798 else
11799 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011800 return result;
11801}
Larry Hastings2f936352014-08-05 14:04:04 +100011802#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011803
11804
11805#ifdef HAVE_SYSCONF
11806static struct constdef posix_constants_sysconf[] = {
11807#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011808 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011809#endif
11810#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011811 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011812#endif
11813#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011814 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011815#endif
11816#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011817 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011818#endif
11819#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011820 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011821#endif
11822#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011823 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011824#endif
11825#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011826 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011827#endif
11828#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011829 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011830#endif
11831#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011832 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011833#endif
11834#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011835 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011836#endif
Fred Draked86ed291999-12-15 15:34:33 +000011837#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011838 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011839#endif
11840#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011841 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011842#endif
Fred Drakec9680921999-12-13 16:37:25 +000011843#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011844 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011845#endif
Fred Drakec9680921999-12-13 16:37:25 +000011846#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011847 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011848#endif
11849#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011850 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011851#endif
11852#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011853 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011854#endif
11855#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011856 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011857#endif
11858#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011859 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011860#endif
Fred Draked86ed291999-12-15 15:34:33 +000011861#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011862 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011863#endif
Fred Drakec9680921999-12-13 16:37:25 +000011864#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011865 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011866#endif
11867#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011868 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011869#endif
11870#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011871 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011872#endif
11873#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011874 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011875#endif
11876#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011877 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011878#endif
Fred Draked86ed291999-12-15 15:34:33 +000011879#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011880 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011881#endif
Fred Drakec9680921999-12-13 16:37:25 +000011882#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011883 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011884#endif
11885#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011886 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011887#endif
11888#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011889 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011890#endif
11891#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011892 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011893#endif
11894#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011895 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011896#endif
11897#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011898 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011899#endif
11900#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011901 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011902#endif
11903#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011904 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011905#endif
11906#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011907 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011908#endif
11909#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011910 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011911#endif
11912#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011913 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011914#endif
11915#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011916 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011917#endif
11918#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011919 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011920#endif
11921#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011922 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011923#endif
11924#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011925 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011926#endif
11927#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011928 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011929#endif
11930#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011931 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011932#endif
11933#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011934 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011935#endif
11936#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011937 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011938#endif
11939#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011940 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011941#endif
11942#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011943 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011944#endif
11945#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011946 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011947#endif
11948#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011949 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011950#endif
Fred Draked86ed291999-12-15 15:34:33 +000011951#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011952 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011953#endif
Fred Drakec9680921999-12-13 16:37:25 +000011954#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011955 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011956#endif
11957#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011958 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011959#endif
11960#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011961 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011962#endif
Fred Draked86ed291999-12-15 15:34:33 +000011963#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011964 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011965#endif
Fred Drakec9680921999-12-13 16:37:25 +000011966#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011967 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011968#endif
Fred Draked86ed291999-12-15 15:34:33 +000011969#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011970 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011971#endif
11972#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011973 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011974#endif
Fred Drakec9680921999-12-13 16:37:25 +000011975#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011976 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011977#endif
11978#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011979 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011980#endif
11981#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011982 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011983#endif
11984#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011985 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011986#endif
Fred Draked86ed291999-12-15 15:34:33 +000011987#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011988 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011989#endif
Fred Drakec9680921999-12-13 16:37:25 +000011990#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011991 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011992#endif
11993#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011994 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011995#endif
11996#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011997 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011998#endif
11999#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000012000 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000012001#endif
12002#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000012003 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000012004#endif
12005#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000012006 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000012007#endif
12008#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000012009 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000012010#endif
Fred Draked86ed291999-12-15 15:34:33 +000012011#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000012012 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000012013#endif
Fred Drakec9680921999-12-13 16:37:25 +000012014#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012015 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012016#endif
12017#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012018 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012019#endif
Fred Draked86ed291999-12-15 15:34:33 +000012020#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012021 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000012022#endif
Fred Drakec9680921999-12-13 16:37:25 +000012023#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012024 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012025#endif
12026#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012027 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012028#endif
12029#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012030 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012031#endif
12032#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012033 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012034#endif
12035#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012036 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012037#endif
12038#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012039 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012040#endif
12041#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012042 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000012043#endif
12044#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000012045 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000012046#endif
12047#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000012048 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000012049#endif
Fred Draked86ed291999-12-15 15:34:33 +000012050#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000012051 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000012052#endif
12053#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000012054 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000012055#endif
Fred Drakec9680921999-12-13 16:37:25 +000012056#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000012057 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000012058#endif
12059#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012060 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012061#endif
12062#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012063 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012064#endif
12065#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012066 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012067#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030012068#ifdef _SC_AIX_REALMEM
12069 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
12070#endif
Fred Drakec9680921999-12-13 16:37:25 +000012071#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012072 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012073#endif
12074#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000012075 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000012076#endif
12077#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000012078 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000012079#endif
12080#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000012081 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000012082#endif
12083#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012084 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000012085#endif
12086#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012087 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000012088#endif
12089#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000012090 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000012091#endif
12092#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012093 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000012094#endif
12095#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012096 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000012097#endif
12098#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000012099 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000012100#endif
12101#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000012102 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000012103#endif
12104#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000012105 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000012106#endif
12107#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000012108 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000012109#endif
12110#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012111 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012112#endif
12113#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012114 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012115#endif
12116#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000012117 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000012118#endif
12119#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012120 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012121#endif
12122#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012123 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012124#endif
12125#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000012126 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000012127#endif
12128#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012129 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012130#endif
12131#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012132 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012133#endif
12134#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012135 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000012136#endif
12137#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000012138 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000012139#endif
12140#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012141 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012142#endif
12143#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012144 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012145#endif
12146#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012147 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000012148#endif
12149#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012150 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012151#endif
12152#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012153 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012154#endif
12155#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012156 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012157#endif
12158#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012159 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012160#endif
12161#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012162 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012163#endif
Fred Draked86ed291999-12-15 15:34:33 +000012164#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000012165 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000012166#endif
Fred Drakec9680921999-12-13 16:37:25 +000012167#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000012168 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000012169#endif
12170#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012171 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012172#endif
12173#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000012174 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000012175#endif
12176#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012177 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012178#endif
12179#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012180 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012181#endif
12182#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012183 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012184#endif
12185#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000012186 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000012187#endif
12188#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012189 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012190#endif
12191#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012192 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012193#endif
12194#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012195 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012196#endif
12197#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012198 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012199#endif
12200#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012201 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000012202#endif
12203#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012204 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000012205#endif
12206#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000012207 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000012208#endif
12209#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012210 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012211#endif
12212#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012213 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012214#endif
12215#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012216 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012217#endif
12218#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000012219 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000012220#endif
12221#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012222 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012223#endif
12224#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012225 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012226#endif
12227#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012228 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012229#endif
12230#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012231 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012232#endif
12233#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012234 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012235#endif
12236#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012237 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012238#endif
12239#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000012240 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000012241#endif
12242#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012243 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012244#endif
12245#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012246 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012247#endif
12248#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012249 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012250#endif
12251#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012252 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000012253#endif
12254#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000012255 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000012256#endif
12257#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012258 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012259#endif
12260#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000012261 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000012262#endif
12263#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012264 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012265#endif
12266#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000012267 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000012268#endif
12269#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000012270 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000012271#endif
12272#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000012273 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000012274#endif
12275#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012276 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000012277#endif
12278#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012279 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012280#endif
12281#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000012282 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000012283#endif
12284#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000012285 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000012286#endif
12287#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012288 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012289#endif
12290#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012291 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012292#endif
12293#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000012294 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000012295#endif
12296#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000012297 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000012298#endif
12299#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000012300 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000012301#endif
12302};
12303
12304static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012305conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000012306{
12307 return conv_confname(arg, valuep, posix_constants_sysconf,
12308 sizeof(posix_constants_sysconf)
12309 / sizeof(struct constdef));
12310}
12311
Larry Hastings2f936352014-08-05 14:04:04 +100012312
12313/*[clinic input]
12314os.sysconf -> long
12315 name: sysconf_confname
12316 /
12317
12318Return an integer-valued system configuration variable.
12319[clinic start generated code]*/
12320
Larry Hastings2f936352014-08-05 14:04:04 +100012321static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012322os_sysconf_impl(PyObject *module, int name)
12323/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012324{
12325 long value;
12326
12327 errno = 0;
12328 value = sysconf(name);
12329 if (value == -1 && errno != 0)
12330 posix_error();
12331 return value;
12332}
12333#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000012334
12335
Fred Drakebec628d1999-12-15 18:31:10 +000012336/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020012337 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000012338 * the exported dictionaries that are used to publish information about the
12339 * names available on the host platform.
12340 *
12341 * Sorting the table at runtime ensures that the table is properly ordered
12342 * when used, even for platforms we're not able to test on. It also makes
12343 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000012344 */
Fred Drakebec628d1999-12-15 18:31:10 +000012345
12346static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012347cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000012348{
12349 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012350 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000012351 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012352 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000012353
12354 return strcmp(c1->name, c2->name);
12355}
12356
12357static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012358setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012359 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012360{
Fred Drakebec628d1999-12-15 18:31:10 +000012361 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000012362 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000012363
12364 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
12365 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000012366 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000012367 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012368
Barry Warsaw3155db32000-04-13 15:20:40 +000012369 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000012370 PyObject *o = PyLong_FromLong(table[i].value);
12371 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
12372 Py_XDECREF(o);
12373 Py_DECREF(d);
12374 return -1;
12375 }
12376 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000012377 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000012378 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000012379}
12380
Fred Drakebec628d1999-12-15 18:31:10 +000012381/* Return -1 on failure, 0 on success. */
12382static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000012383setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012384{
12385#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000012386 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000012387 sizeof(posix_constants_pathconf)
12388 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012389 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012390 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012391#endif
12392#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000012393 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000012394 sizeof(posix_constants_confstr)
12395 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012396 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012397 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012398#endif
12399#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000012400 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000012401 sizeof(posix_constants_sysconf)
12402 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012403 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012404 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012405#endif
Fred Drakebec628d1999-12-15 18:31:10 +000012406 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000012407}
Fred Draked86ed291999-12-15 15:34:33 +000012408
12409
Larry Hastings2f936352014-08-05 14:04:04 +100012410/*[clinic input]
12411os.abort
12412
12413Abort the interpreter immediately.
12414
12415This function 'dumps core' or otherwise fails in the hardest way possible
12416on the hosting operating system. This function never returns.
12417[clinic start generated code]*/
12418
Larry Hastings2f936352014-08-05 14:04:04 +100012419static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012420os_abort_impl(PyObject *module)
12421/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012422{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012423 abort();
12424 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010012425#ifndef __clang__
12426 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
12427 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
12428 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012429 Py_FatalError("abort() called from Python code didn't abort!");
12430 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010012431#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012432}
Fred Drakebec628d1999-12-15 18:31:10 +000012433
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000012434#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012435/* Grab ShellExecute dynamically from shell32 */
12436static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012437static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
12438 LPCWSTR, INT);
12439static int
12440check_ShellExecute()
12441{
12442 HINSTANCE hShell32;
12443
12444 /* only recheck */
12445 if (-1 == has_ShellExecute) {
12446 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070012447 /* Security note: this call is not vulnerable to "DLL hijacking".
12448 SHELL32 is part of "KnownDLLs" and so Windows always load
12449 the system SHELL32.DLL, even if there is another SHELL32.DLL
12450 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080012451 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080012452 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080012453 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
12454 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070012455 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012456 } else {
12457 has_ShellExecute = 0;
12458 }
Tony Roberts4860f012019-02-02 18:16:42 +010012459 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012460 }
12461 return has_ShellExecute;
12462}
12463
12464
Steve Dowercc16be82016-09-08 10:35:16 -070012465/*[clinic input]
12466os.startfile
12467 filepath: path_t
12468 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000012469
Steve Dowercc16be82016-09-08 10:35:16 -070012470Start a file with its associated application.
12471
12472When "operation" is not specified or "open", this acts like
12473double-clicking the file in Explorer, or giving the file name as an
12474argument to the DOS "start" command: the file is opened with whatever
12475application (if any) its extension is associated.
12476When another "operation" is given, it specifies what should be done with
12477the file. A typical operation is "print".
12478
12479startfile returns as soon as the associated application is launched.
12480There is no option to wait for the application to close, and no way
12481to retrieve the application's exit status.
12482
12483The filepath is relative to the current directory. If you want to use
12484an absolute path, make sure the first character is not a slash ("/");
12485the underlying Win32 ShellExecute function doesn't work if it is.
12486[clinic start generated code]*/
12487
12488static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020012489os_startfile_impl(PyObject *module, path_t *filepath,
12490 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030012491/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070012492{
12493 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012494
12495 if(!check_ShellExecute()) {
12496 /* If the OS doesn't have ShellExecute, return a
12497 NotImplementedError. */
12498 return PyErr_Format(PyExc_NotImplementedError,
12499 "startfile not available on this platform");
12500 }
12501
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012502 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080012503 return NULL;
12504 }
12505
Victor Stinner8c62be82010-05-06 00:08:46 +000012506 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070012507 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080012508 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000012509 Py_END_ALLOW_THREADS
12510
Victor Stinner8c62be82010-05-06 00:08:46 +000012511 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070012512 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020012513 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012514 }
Steve Dowercc16be82016-09-08 10:35:16 -070012515 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000012516}
Larry Hastings2f936352014-08-05 14:04:04 +100012517#endif /* MS_WINDOWS */
12518
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012519
Martin v. Löwis438b5342002-12-27 10:16:42 +000012520#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100012521/*[clinic input]
12522os.getloadavg
12523
12524Return average recent system load information.
12525
12526Return the number of processes in the system run queue averaged over
12527the last 1, 5, and 15 minutes as a tuple of three floats.
12528Raises OSError if the load average was unobtainable.
12529[clinic start generated code]*/
12530
Larry Hastings2f936352014-08-05 14:04:04 +100012531static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012532os_getloadavg_impl(PyObject *module)
12533/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000012534{
12535 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000012536 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000012537 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
12538 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000012539 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000012540 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000012541}
Larry Hastings2f936352014-08-05 14:04:04 +100012542#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000012543
Larry Hastings2f936352014-08-05 14:04:04 +100012544
12545/*[clinic input]
12546os.device_encoding
12547 fd: int
12548
12549Return a string describing the encoding of a terminal's file descriptor.
12550
12551The file descriptor must be attached to a terminal.
12552If the device is not a terminal, return None.
12553[clinic start generated code]*/
12554
Larry Hastings2f936352014-08-05 14:04:04 +100012555static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012556os_device_encoding_impl(PyObject *module, int fd)
12557/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012558{
Brett Cannonefb00c02012-02-29 18:31:31 -050012559 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000012560}
12561
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012562
Larry Hastings2f936352014-08-05 14:04:04 +100012563#ifdef HAVE_SETRESUID
12564/*[clinic input]
12565os.setresuid
12566
12567 ruid: uid_t
12568 euid: uid_t
12569 suid: uid_t
12570 /
12571
12572Set the current process's real, effective, and saved user ids.
12573[clinic start generated code]*/
12574
Larry Hastings2f936352014-08-05 14:04:04 +100012575static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012576os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12577/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012578{
Victor Stinner8c62be82010-05-06 00:08:46 +000012579 if (setresuid(ruid, euid, suid) < 0)
12580 return posix_error();
12581 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012582}
Larry Hastings2f936352014-08-05 14:04:04 +100012583#endif /* HAVE_SETRESUID */
12584
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012585
12586#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012587/*[clinic input]
12588os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012589
Larry Hastings2f936352014-08-05 14:04:04 +100012590 rgid: gid_t
12591 egid: gid_t
12592 sgid: gid_t
12593 /
12594
12595Set the current process's real, effective, and saved group ids.
12596[clinic start generated code]*/
12597
Larry Hastings2f936352014-08-05 14:04:04 +100012598static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012599os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12600/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012601{
Victor Stinner8c62be82010-05-06 00:08:46 +000012602 if (setresgid(rgid, egid, sgid) < 0)
12603 return posix_error();
12604 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012605}
Larry Hastings2f936352014-08-05 14:04:04 +100012606#endif /* HAVE_SETRESGID */
12607
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012608
12609#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012610/*[clinic input]
12611os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012612
Larry Hastings2f936352014-08-05 14:04:04 +100012613Return a tuple of the current process's real, effective, and saved user ids.
12614[clinic start generated code]*/
12615
Larry Hastings2f936352014-08-05 14:04:04 +100012616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012617os_getresuid_impl(PyObject *module)
12618/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012619{
Victor Stinner8c62be82010-05-06 00:08:46 +000012620 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012621 if (getresuid(&ruid, &euid, &suid) < 0)
12622 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012623 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12624 _PyLong_FromUid(euid),
12625 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012626}
Larry Hastings2f936352014-08-05 14:04:04 +100012627#endif /* HAVE_GETRESUID */
12628
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012629
12630#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012631/*[clinic input]
12632os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012633
Larry Hastings2f936352014-08-05 14:04:04 +100012634Return a tuple of the current process's real, effective, and saved group ids.
12635[clinic start generated code]*/
12636
Larry Hastings2f936352014-08-05 14:04:04 +100012637static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012638os_getresgid_impl(PyObject *module)
12639/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012640{
12641 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012642 if (getresgid(&rgid, &egid, &sgid) < 0)
12643 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012644 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12645 _PyLong_FromGid(egid),
12646 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012647}
Larry Hastings2f936352014-08-05 14:04:04 +100012648#endif /* HAVE_GETRESGID */
12649
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012650
Benjamin Peterson9428d532011-09-14 11:45:52 -040012651#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012652/*[clinic input]
12653os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012654
Larry Hastings2f936352014-08-05 14:04:04 +100012655 path: path_t(allow_fd=True)
12656 attribute: path_t
12657 *
12658 follow_symlinks: bool = True
12659
12660Return the value of extended attribute attribute on path.
12661
BNMetricsb9427072018-11-02 15:20:19 +000012662path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012663If follow_symlinks is False, and the last element of the path is a symbolic
12664 link, getxattr will examine the symbolic link itself instead of the file
12665 the link points to.
12666
12667[clinic start generated code]*/
12668
Larry Hastings2f936352014-08-05 14:04:04 +100012669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012670os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012671 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012672/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012673{
12674 Py_ssize_t i;
12675 PyObject *buffer = NULL;
12676
12677 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12678 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012679
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012680 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12681 return NULL;
12682 }
12683
Larry Hastings9cf065c2012-06-22 16:30:09 -070012684 for (i = 0; ; i++) {
12685 void *ptr;
12686 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012687 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012688 Py_ssize_t buffer_size = buffer_sizes[i];
12689 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012690 path_error(path);
12691 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012692 }
12693 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12694 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012695 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012696 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012697
Larry Hastings9cf065c2012-06-22 16:30:09 -070012698 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012699 if (path->fd >= 0)
12700 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012701 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012702 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012703 else
Larry Hastings2f936352014-08-05 14:04:04 +100012704 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012705 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012706
Larry Hastings9cf065c2012-06-22 16:30:09 -070012707 if (result < 0) {
12708 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012709 if (errno == ERANGE)
12710 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012711 path_error(path);
12712 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012713 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012714
Larry Hastings9cf065c2012-06-22 16:30:09 -070012715 if (result != buffer_size) {
12716 /* Can only shrink. */
12717 _PyBytes_Resize(&buffer, result);
12718 }
12719 break;
12720 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012721
Larry Hastings9cf065c2012-06-22 16:30:09 -070012722 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012723}
12724
Larry Hastings2f936352014-08-05 14:04:04 +100012725
12726/*[clinic input]
12727os.setxattr
12728
12729 path: path_t(allow_fd=True)
12730 attribute: path_t
12731 value: Py_buffer
12732 flags: int = 0
12733 *
12734 follow_symlinks: bool = True
12735
12736Set extended attribute attribute on path to value.
12737
BNMetricsb9427072018-11-02 15:20:19 +000012738path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012739If follow_symlinks is False, and the last element of the path is a symbolic
12740 link, setxattr will modify the symbolic link itself instead of the file
12741 the link points to.
12742
12743[clinic start generated code]*/
12744
Benjamin Peterson799bd802011-08-31 22:15:17 -040012745static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012746os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012747 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012748/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012749{
Larry Hastings2f936352014-08-05 14:04:04 +100012750 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012751
Larry Hastings2f936352014-08-05 14:04:04 +100012752 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012753 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012754
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012755 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12756 value->buf, value->len, flags) < 0) {
12757 return NULL;
12758 }
12759
Benjamin Peterson799bd802011-08-31 22:15:17 -040012760 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012761 if (path->fd > -1)
12762 result = fsetxattr(path->fd, attribute->narrow,
12763 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012764 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012765 result = setxattr(path->narrow, attribute->narrow,
12766 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012767 else
Larry Hastings2f936352014-08-05 14:04:04 +100012768 result = lsetxattr(path->narrow, attribute->narrow,
12769 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012770 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012771
Larry Hastings9cf065c2012-06-22 16:30:09 -070012772 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012773 path_error(path);
12774 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012775 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012776
Larry Hastings2f936352014-08-05 14:04:04 +100012777 Py_RETURN_NONE;
12778}
12779
12780
12781/*[clinic input]
12782os.removexattr
12783
12784 path: path_t(allow_fd=True)
12785 attribute: path_t
12786 *
12787 follow_symlinks: bool = True
12788
12789Remove extended attribute attribute on path.
12790
BNMetricsb9427072018-11-02 15:20:19 +000012791path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012792If follow_symlinks is False, and the last element of the path is a symbolic
12793 link, removexattr will modify the symbolic link itself instead of the file
12794 the link points to.
12795
12796[clinic start generated code]*/
12797
Larry Hastings2f936352014-08-05 14:04:04 +100012798static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012799os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012800 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012801/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012802{
12803 ssize_t result;
12804
12805 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12806 return NULL;
12807
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012808 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12809 return NULL;
12810 }
12811
Larry Hastings2f936352014-08-05 14:04:04 +100012812 Py_BEGIN_ALLOW_THREADS;
12813 if (path->fd > -1)
12814 result = fremovexattr(path->fd, attribute->narrow);
12815 else if (follow_symlinks)
12816 result = removexattr(path->narrow, attribute->narrow);
12817 else
12818 result = lremovexattr(path->narrow, attribute->narrow);
12819 Py_END_ALLOW_THREADS;
12820
12821 if (result) {
12822 return path_error(path);
12823 }
12824
12825 Py_RETURN_NONE;
12826}
12827
12828
12829/*[clinic input]
12830os.listxattr
12831
12832 path: path_t(allow_fd=True, nullable=True) = None
12833 *
12834 follow_symlinks: bool = True
12835
12836Return a list of extended attributes on path.
12837
BNMetricsb9427072018-11-02 15:20:19 +000012838path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012839if path is None, listxattr will examine the current directory.
12840If follow_symlinks is False, and the last element of the path is a symbolic
12841 link, listxattr will examine the symbolic link itself instead of the file
12842 the link points to.
12843[clinic start generated code]*/
12844
Larry Hastings2f936352014-08-05 14:04:04 +100012845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012846os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012847/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012848{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012849 Py_ssize_t i;
12850 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012851 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012852 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012853
Larry Hastings2f936352014-08-05 14:04:04 +100012854 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012855 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012856
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012857 if (PySys_Audit("os.listxattr", "(O)",
12858 path->object ? path->object : Py_None) < 0) {
12859 return NULL;
12860 }
12861
Larry Hastings2f936352014-08-05 14:04:04 +100012862 name = path->narrow ? path->narrow : ".";
12863
Larry Hastings9cf065c2012-06-22 16:30:09 -070012864 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012865 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012866 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012867 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012868 Py_ssize_t buffer_size = buffer_sizes[i];
12869 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012870 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012871 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012872 break;
12873 }
Victor Stinner00d7abd2020-12-01 09:56:42 +010012874 buffer = PyMem_Malloc(buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012875 if (!buffer) {
12876 PyErr_NoMemory();
12877 break;
12878 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012879
Larry Hastings9cf065c2012-06-22 16:30:09 -070012880 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012881 if (path->fd > -1)
12882 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012883 else if (follow_symlinks)
12884 length = listxattr(name, buffer, buffer_size);
12885 else
12886 length = llistxattr(name, buffer, buffer_size);
12887 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012888
Larry Hastings9cf065c2012-06-22 16:30:09 -070012889 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012890 if (errno == ERANGE) {
Victor Stinner00d7abd2020-12-01 09:56:42 +010012891 PyMem_Free(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012892 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012893 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012894 }
Larry Hastings2f936352014-08-05 14:04:04 +100012895 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012896 break;
12897 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012898
Larry Hastings9cf065c2012-06-22 16:30:09 -070012899 result = PyList_New(0);
12900 if (!result) {
12901 goto exit;
12902 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012903
Larry Hastings9cf065c2012-06-22 16:30:09 -070012904 end = buffer + length;
12905 for (trace = start = buffer; trace != end; trace++) {
12906 if (!*trace) {
12907 int error;
12908 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12909 trace - start);
12910 if (!attribute) {
12911 Py_DECREF(result);
12912 result = NULL;
12913 goto exit;
12914 }
12915 error = PyList_Append(result, attribute);
12916 Py_DECREF(attribute);
12917 if (error) {
12918 Py_DECREF(result);
12919 result = NULL;
12920 goto exit;
12921 }
12922 start = trace + 1;
12923 }
12924 }
12925 break;
12926 }
12927exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012928 if (buffer)
Victor Stinner00d7abd2020-12-01 09:56:42 +010012929 PyMem_Free(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012930 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012931}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012932#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012933
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012934
Larry Hastings2f936352014-08-05 14:04:04 +100012935/*[clinic input]
12936os.urandom
12937
12938 size: Py_ssize_t
12939 /
12940
12941Return a bytes object containing random bytes suitable for cryptographic use.
12942[clinic start generated code]*/
12943
Larry Hastings2f936352014-08-05 14:04:04 +100012944static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012945os_urandom_impl(PyObject *module, Py_ssize_t size)
12946/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012947{
12948 PyObject *bytes;
12949 int result;
12950
Georg Brandl2fb477c2012-02-21 00:33:36 +010012951 if (size < 0)
12952 return PyErr_Format(PyExc_ValueError,
12953 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012954 bytes = PyBytes_FromStringAndSize(NULL, size);
12955 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012956 return NULL;
12957
Victor Stinnere66987e2016-09-06 16:33:52 -070012958 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012959 if (result == -1) {
12960 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012961 return NULL;
12962 }
Larry Hastings2f936352014-08-05 14:04:04 +100012963 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012964}
12965
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012966#ifdef HAVE_MEMFD_CREATE
12967/*[clinic input]
12968os.memfd_create
12969
12970 name: FSConverter
12971 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12972
12973[clinic start generated code]*/
12974
12975static PyObject *
12976os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12977/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12978{
12979 int fd;
12980 const char *bytes = PyBytes_AS_STRING(name);
12981 Py_BEGIN_ALLOW_THREADS
12982 fd = memfd_create(bytes, flags);
12983 Py_END_ALLOW_THREADS
12984 if (fd == -1) {
12985 return PyErr_SetFromErrno(PyExc_OSError);
12986 }
12987 return PyLong_FromLong(fd);
12988}
12989#endif
12990
Christian Heimescd9fed62020-11-13 19:48:52 +010012991#ifdef HAVE_EVENTFD
12992/*[clinic input]
12993os.eventfd
12994
12995 initval: unsigned_int
12996 flags: int(c_default="EFD_CLOEXEC") = EFD_CLOEXEC
12997
12998Creates and returns an event notification file descriptor.
12999[clinic start generated code]*/
13000
13001static PyObject *
13002os_eventfd_impl(PyObject *module, unsigned int initval, int flags)
13003/*[clinic end generated code: output=ce9c9bbd1446f2de input=66203e3c50c4028b]*/
13004
13005{
13006 /* initval is limited to uint32_t, internal counter is uint64_t */
13007 int fd;
13008 Py_BEGIN_ALLOW_THREADS
13009 fd = eventfd(initval, flags);
13010 Py_END_ALLOW_THREADS
13011 if (fd == -1) {
13012 return PyErr_SetFromErrno(PyExc_OSError);
13013 }
13014 return PyLong_FromLong(fd);
13015}
13016
13017/*[clinic input]
13018os.eventfd_read
13019
13020 fd: fildes
13021
13022Read eventfd value
13023[clinic start generated code]*/
13024
13025static PyObject *
13026os_eventfd_read_impl(PyObject *module, int fd)
13027/*[clinic end generated code: output=8f2c7b59a3521fd1 input=110f8b57fa596afe]*/
13028{
13029 eventfd_t value;
13030 int result;
13031 Py_BEGIN_ALLOW_THREADS
13032 result = eventfd_read(fd, &value);
13033 Py_END_ALLOW_THREADS
13034 if (result == -1) {
13035 return PyErr_SetFromErrno(PyExc_OSError);
13036 }
13037 return PyLong_FromUnsignedLongLong(value);
13038}
13039
13040/*[clinic input]
13041os.eventfd_write
13042
13043 fd: fildes
13044 value: unsigned_long_long
13045
13046Write eventfd value.
13047[clinic start generated code]*/
13048
13049static PyObject *
13050os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value)
13051/*[clinic end generated code: output=bebd9040bbf987f5 input=156de8555be5a949]*/
13052{
13053 int result;
13054 Py_BEGIN_ALLOW_THREADS
13055 result = eventfd_write(fd, value);
13056 Py_END_ALLOW_THREADS
13057 if (result == -1) {
13058 return PyErr_SetFromErrno(PyExc_OSError);
13059 }
13060 Py_RETURN_NONE;
13061}
13062#endif /* HAVE_EVENTFD */
13063
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013064/* Terminal size querying */
13065
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013066PyDoc_STRVAR(TerminalSize_docstring,
13067 "A tuple of (columns, lines) for holding terminal window size");
13068
13069static PyStructSequence_Field TerminalSize_fields[] = {
13070 {"columns", "width of the terminal window in characters"},
13071 {"lines", "height of the terminal window in characters"},
13072 {NULL, NULL}
13073};
13074
13075static PyStructSequence_Desc TerminalSize_desc = {
13076 "os.terminal_size",
13077 TerminalSize_docstring,
13078 TerminalSize_fields,
13079 2,
13080};
13081
13082#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013083/*[clinic input]
13084os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013085
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013086 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
13087 /
13088
13089Return the size of the terminal window as (columns, lines).
13090
13091The optional argument fd (default standard output) specifies
13092which file descriptor should be queried.
13093
13094If the file descriptor is not connected to a terminal, an OSError
13095is thrown.
13096
13097This function will only be defined if an implementation is
13098available for this system.
13099
13100shutil.get_terminal_size is the high-level function which should
13101normally be used, os.get_terminal_size is the low-level implementation.
13102[clinic start generated code]*/
13103
13104static PyObject *
13105os_get_terminal_size_impl(PyObject *module, int fd)
13106/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013107{
13108 int columns, lines;
13109 PyObject *termsize;
13110
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013111 /* Under some conditions stdout may not be connected and
13112 * fileno(stdout) may point to an invalid file descriptor. For example
13113 * GUI apps don't have valid standard streams by default.
13114 *
13115 * If this happens, and the optional fd argument is not present,
13116 * the ioctl below will fail returning EBADF. This is what we want.
13117 */
13118
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013119#ifdef TERMSIZE_USE_IOCTL
13120 {
13121 struct winsize w;
13122 if (ioctl(fd, TIOCGWINSZ, &w))
13123 return PyErr_SetFromErrno(PyExc_OSError);
13124 columns = w.ws_col;
13125 lines = w.ws_row;
13126 }
13127#endif /* TERMSIZE_USE_IOCTL */
13128
13129#ifdef TERMSIZE_USE_CONIO
13130 {
13131 DWORD nhandle;
13132 HANDLE handle;
13133 CONSOLE_SCREEN_BUFFER_INFO csbi;
13134 switch (fd) {
13135 case 0: nhandle = STD_INPUT_HANDLE;
13136 break;
13137 case 1: nhandle = STD_OUTPUT_HANDLE;
13138 break;
13139 case 2: nhandle = STD_ERROR_HANDLE;
13140 break;
13141 default:
13142 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
13143 }
13144 handle = GetStdHandle(nhandle);
13145 if (handle == NULL)
13146 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
13147 if (handle == INVALID_HANDLE_VALUE)
13148 return PyErr_SetFromWindowsErr(0);
13149
13150 if (!GetConsoleScreenBufferInfo(handle, &csbi))
13151 return PyErr_SetFromWindowsErr(0);
13152
13153 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
13154 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
13155 }
13156#endif /* TERMSIZE_USE_CONIO */
13157
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013158 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013159 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013160 if (termsize == NULL)
13161 return NULL;
13162 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
13163 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
13164 if (PyErr_Occurred()) {
13165 Py_DECREF(termsize);
13166 return NULL;
13167 }
13168 return termsize;
13169}
13170#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
13171
Larry Hastings2f936352014-08-05 14:04:04 +100013172
13173/*[clinic input]
13174os.cpu_count
13175
Charles-François Natali80d62e62015-08-13 20:37:08 +010013176Return the number of CPUs in the system; return None if indeterminable.
13177
13178This number is not equivalent to the number of CPUs the current process can
13179use. The number of usable CPUs can be obtained with
13180``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100013181[clinic start generated code]*/
13182
Larry Hastings2f936352014-08-05 14:04:04 +100013183static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013184os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013185/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013186{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013187 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013188#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010013189 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013190#elif defined(__hpux)
13191 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
13192#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
13193 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
pxinwr3405e052020-08-07 13:21:52 +080013194#elif defined(__VXWORKS__)
13195 ncpu = _Py_popcount32(vxCpuEnabledGet());
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013196#elif defined(__DragonFly__) || \
13197 defined(__OpenBSD__) || \
13198 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013199 defined(__NetBSD__) || \
13200 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020013201 int mib[2];
13202 size_t len = sizeof(ncpu);
13203 mib[0] = CTL_HW;
13204 mib[1] = HW_NCPU;
13205 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
13206 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013207#endif
13208 if (ncpu >= 1)
13209 return PyLong_FromLong(ncpu);
13210 else
13211 Py_RETURN_NONE;
13212}
13213
Victor Stinnerdaf45552013-08-28 00:53:59 +020013214
Larry Hastings2f936352014-08-05 14:04:04 +100013215/*[clinic input]
13216os.get_inheritable -> bool
13217
13218 fd: int
13219 /
13220
13221Get the close-on-exe flag of the specified file descriptor.
13222[clinic start generated code]*/
13223
Larry Hastings2f936352014-08-05 14:04:04 +100013224static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013225os_get_inheritable_impl(PyObject *module, int fd)
13226/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013227{
Steve Dower8fc89802015-04-12 00:26:27 -040013228 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040013229 _Py_BEGIN_SUPPRESS_IPH
13230 return_value = _Py_get_inheritable(fd);
13231 _Py_END_SUPPRESS_IPH
13232 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100013233}
13234
13235
13236/*[clinic input]
13237os.set_inheritable
13238 fd: int
13239 inheritable: int
13240 /
13241
13242Set the inheritable flag of the specified file descriptor.
13243[clinic start generated code]*/
13244
Larry Hastings2f936352014-08-05 14:04:04 +100013245static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013246os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
13247/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020013248{
Steve Dower8fc89802015-04-12 00:26:27 -040013249 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013250
Steve Dower8fc89802015-04-12 00:26:27 -040013251 _Py_BEGIN_SUPPRESS_IPH
13252 result = _Py_set_inheritable(fd, inheritable, NULL);
13253 _Py_END_SUPPRESS_IPH
13254 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020013255 return NULL;
13256 Py_RETURN_NONE;
13257}
13258
13259
13260#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100013261/*[clinic input]
13262os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070013263 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013264 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020013265
Larry Hastings2f936352014-08-05 14:04:04 +100013266Get the close-on-exe flag of the specified file descriptor.
13267[clinic start generated code]*/
13268
Larry Hastings2f936352014-08-05 14:04:04 +100013269static int
Benjamin Petersonca470632016-09-06 13:47:26 -070013270os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070013271/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013272{
13273 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013274
13275 if (!GetHandleInformation((HANDLE)handle, &flags)) {
13276 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100013277 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013278 }
13279
Larry Hastings2f936352014-08-05 14:04:04 +100013280 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013281}
13282
Victor Stinnerdaf45552013-08-28 00:53:59 +020013283
Larry Hastings2f936352014-08-05 14:04:04 +100013284/*[clinic input]
13285os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070013286 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013287 inheritable: bool
13288 /
13289
13290Set the inheritable flag of the specified handle.
13291[clinic start generated code]*/
13292
Larry Hastings2f936352014-08-05 14:04:04 +100013293static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070013294os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040013295 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070013296/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013297{
13298 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013299 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
13300 PyErr_SetFromWindowsErr(0);
13301 return NULL;
13302 }
13303 Py_RETURN_NONE;
13304}
Larry Hastings2f936352014-08-05 14:04:04 +100013305#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013306
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013307#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013308/*[clinic input]
13309os.get_blocking -> bool
13310 fd: int
13311 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013312
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013313Get the blocking mode of the file descriptor.
13314
13315Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
13316[clinic start generated code]*/
13317
13318static int
13319os_get_blocking_impl(PyObject *module, int fd)
13320/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013321{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013322 int blocking;
13323
Steve Dower8fc89802015-04-12 00:26:27 -040013324 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013325 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040013326 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013327 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013328}
13329
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013330/*[clinic input]
13331os.set_blocking
13332 fd: int
13333 blocking: bool(accept={int})
13334 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013335
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013336Set the blocking mode of the specified file descriptor.
13337
13338Set the O_NONBLOCK flag if blocking is False,
13339clear the O_NONBLOCK flag otherwise.
13340[clinic start generated code]*/
13341
13342static PyObject *
13343os_set_blocking_impl(PyObject *module, int fd, int blocking)
13344/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013345{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013346 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013347
Steve Dower8fc89802015-04-12 00:26:27 -040013348 _Py_BEGIN_SUPPRESS_IPH
13349 result = _Py_set_blocking(fd, blocking);
13350 _Py_END_SUPPRESS_IPH
13351 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013352 return NULL;
13353 Py_RETURN_NONE;
13354}
13355#endif /* !MS_WINDOWS */
13356
13357
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013358/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080013359class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013360[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080013361/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013362
13363typedef struct {
13364 PyObject_HEAD
13365 PyObject *name;
13366 PyObject *path;
13367 PyObject *stat;
13368 PyObject *lstat;
13369#ifdef MS_WINDOWS
13370 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010013371 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010013372 int got_file_index;
13373#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010013374#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013375 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013376#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013377 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013378 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010013379#endif
13380} DirEntry;
13381
Eddie Elizondob3966632019-11-05 07:16:14 -080013382static PyObject *
13383_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
13384{
13385 PyErr_Format(PyExc_TypeError,
13386 "cannot create '%.100s' instances", _PyType_Name(type));
13387 return NULL;
13388}
13389
Victor Stinner6036e442015-03-08 01:58:04 +010013390static void
13391DirEntry_dealloc(DirEntry *entry)
13392{
Eddie Elizondob3966632019-11-05 07:16:14 -080013393 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010013394 Py_XDECREF(entry->name);
13395 Py_XDECREF(entry->path);
13396 Py_XDECREF(entry->stat);
13397 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080013398 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13399 free_func(entry);
13400 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013401}
13402
13403/* Forward reference */
13404static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013405DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13406 int follow_symlinks, unsigned short mode_bits);
Victor Stinner6036e442015-03-08 01:58:04 +010013407
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013408/*[clinic input]
13409os.DirEntry.is_symlink -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013410 defining_class: defining_class
13411 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013412
13413Return True if the entry is a symbolic link; cached per entry.
13414[clinic start generated code]*/
13415
Victor Stinner6036e442015-03-08 01:58:04 +010013416static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013417os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
13418/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013419{
13420#ifdef MS_WINDOWS
13421 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010013422#elif defined(HAVE_DIRENT_D_TYPE)
13423 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013424 if (self->d_type != DT_UNKNOWN)
13425 return self->d_type == DT_LNK;
13426 else
Victor Stinner97f33c32020-05-14 18:05:58 +020013427 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010013428#else
13429 /* POSIX without d_type */
Victor Stinner97f33c32020-05-14 18:05:58 +020013430 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010013431#endif
13432}
13433
13434static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013435DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
Victor Stinner6036e442015-03-08 01:58:04 +010013436{
13437 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013438 STRUCT_STAT st;
13439 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010013440
13441#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013442 if (!PyUnicode_FSDecoder(self->path, &ub))
13443 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013444#if USE_UNICODE_WCHAR_CACHE
13445_Py_COMP_DIAG_PUSH
13446_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013447 const wchar_t *path = PyUnicode_AsUnicode(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013448_Py_COMP_DIAG_POP
13449#else /* USE_UNICODE_WCHAR_CACHE */
13450 wchar_t *path = PyUnicode_AsWideCharString(ub, NULL);
13451 Py_DECREF(ub);
13452#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013453#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013454 if (!PyUnicode_FSConverter(self->path, &ub))
13455 return NULL;
13456 const char *path = PyBytes_AS_STRING(ub);
13457 if (self->dir_fd != DEFAULT_DIR_FD) {
13458#ifdef HAVE_FSTATAT
Ronald Oussoren41761932020-11-08 10:05:27 +010013459 if (HAVE_FSTATAT_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013460 result = fstatat(self->dir_fd, path, &st,
13461 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +010013462 } else
13463
13464#endif /* HAVE_FSTATAT */
13465 {
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013466 Py_DECREF(ub);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013467 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
13468 return NULL;
Ronald Oussoren41761932020-11-08 10:05:27 +010013469 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013470 }
13471 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013472#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013473 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013474 if (follow_symlinks)
13475 result = STAT(path, &st);
13476 else
13477 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013478 }
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013479#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE
13480 PyMem_Free(path);
13481#else /* USE_UNICODE_WCHAR_CACHE */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013482 Py_DECREF(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013483#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013484
13485 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013486 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013487
Victor Stinner97f33c32020-05-14 18:05:58 +020013488 return _pystat_fromstructstat(module, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010013489}
13490
13491static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013492DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
Victor Stinner6036e442015-03-08 01:58:04 +010013493{
13494 if (!self->lstat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013495 PyObject *module = PyType_GetModule(defining_class);
Victor Stinner6036e442015-03-08 01:58:04 +010013496#ifdef MS_WINDOWS
Victor Stinner97f33c32020-05-14 18:05:58 +020013497 self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010013498#else /* POSIX */
Victor Stinner97f33c32020-05-14 18:05:58 +020013499 self->lstat = DirEntry_fetch_stat(module, self, 0);
Victor Stinner6036e442015-03-08 01:58:04 +010013500#endif
13501 }
13502 Py_XINCREF(self->lstat);
13503 return self->lstat;
13504}
13505
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013506/*[clinic input]
13507os.DirEntry.stat
Victor Stinner97f33c32020-05-14 18:05:58 +020013508 defining_class: defining_class
13509 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013510 *
13511 follow_symlinks: bool = True
13512
13513Return stat_result object for the entry; cached per entry.
13514[clinic start generated code]*/
13515
Victor Stinner6036e442015-03-08 01:58:04 +010013516static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013517os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
13518 int follow_symlinks)
13519/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013520{
Victor Stinner97f33c32020-05-14 18:05:58 +020013521 if (!follow_symlinks) {
13522 return DirEntry_get_lstat(defining_class, self);
13523 }
Victor Stinner6036e442015-03-08 01:58:04 +010013524
13525 if (!self->stat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013526 int result = os_DirEntry_is_symlink_impl(self, defining_class);
13527 if (result == -1) {
Victor Stinner6036e442015-03-08 01:58:04 +010013528 return NULL;
Victor Stinner97f33c32020-05-14 18:05:58 +020013529 }
13530 if (result) {
13531 PyObject *module = PyType_GetModule(defining_class);
13532 self->stat = DirEntry_fetch_stat(module, self, 1);
13533 }
13534 else {
13535 self->stat = DirEntry_get_lstat(defining_class, self);
13536 }
Victor Stinner6036e442015-03-08 01:58:04 +010013537 }
13538
13539 Py_XINCREF(self->stat);
13540 return self->stat;
13541}
13542
Victor Stinner6036e442015-03-08 01:58:04 +010013543/* Set exception and return -1 on error, 0 for False, 1 for True */
13544static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013545DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13546 int follow_symlinks, unsigned short mode_bits)
Victor Stinner6036e442015-03-08 01:58:04 +010013547{
13548 PyObject *stat = NULL;
13549 PyObject *st_mode = NULL;
13550 long mode;
13551 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010013552#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013553 int is_symlink;
13554 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010013555#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013556#ifdef MS_WINDOWS
13557 unsigned long dir_bits;
13558#endif
13559
13560#ifdef MS_WINDOWS
13561 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
13562 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010013563#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013564 is_symlink = self->d_type == DT_LNK;
13565 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
13566#endif
13567
Victor Stinner35a97c02015-03-08 02:59:09 +010013568#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013569 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010013570#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020013571 stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010013572 if (!stat) {
13573 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
13574 /* If file doesn't exist (anymore), then return False
13575 (i.e., say it's not a file/directory) */
13576 PyErr_Clear();
13577 return 0;
13578 }
13579 goto error;
13580 }
Victor Stinner97f33c32020-05-14 18:05:58 +020013581 _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
13582 st_mode = PyObject_GetAttr(stat, state->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010013583 if (!st_mode)
13584 goto error;
13585
13586 mode = PyLong_AsLong(st_mode);
13587 if (mode == -1 && PyErr_Occurred())
13588 goto error;
13589 Py_CLEAR(st_mode);
13590 Py_CLEAR(stat);
13591 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010013592#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013593 }
13594 else if (is_symlink) {
13595 assert(mode_bits != S_IFLNK);
13596 result = 0;
13597 }
13598 else {
13599 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
13600#ifdef MS_WINDOWS
13601 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
13602 if (mode_bits == S_IFDIR)
13603 result = dir_bits != 0;
13604 else
13605 result = dir_bits == 0;
13606#else /* POSIX */
13607 if (mode_bits == S_IFDIR)
13608 result = self->d_type == DT_DIR;
13609 else
13610 result = self->d_type == DT_REG;
13611#endif
13612 }
Victor Stinner35a97c02015-03-08 02:59:09 +010013613#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013614
13615 return result;
13616
13617error:
13618 Py_XDECREF(st_mode);
13619 Py_XDECREF(stat);
13620 return -1;
13621}
13622
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013623/*[clinic input]
13624os.DirEntry.is_dir -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013625 defining_class: defining_class
13626 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013627 *
13628 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010013629
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013630Return True if the entry is a directory; cached per entry.
13631[clinic start generated code]*/
13632
13633static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013634os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
13635 int follow_symlinks)
13636/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013637{
Victor Stinner97f33c32020-05-14 18:05:58 +020013638 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010013639}
13640
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013641/*[clinic input]
13642os.DirEntry.is_file -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013643 defining_class: defining_class
13644 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013645 *
13646 follow_symlinks: bool = True
13647
13648Return True if the entry is a file; cached per entry.
13649[clinic start generated code]*/
13650
13651static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013652os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
13653 int follow_symlinks)
13654/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013655{
Victor Stinner97f33c32020-05-14 18:05:58 +020013656 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010013657}
13658
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013659/*[clinic input]
13660os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010013661
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013662Return inode of the entry; cached per entry.
13663[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013664
13665static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013666os_DirEntry_inode_impl(DirEntry *self)
13667/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013668{
13669#ifdef MS_WINDOWS
13670 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013671 PyObject *unicode;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013672 STRUCT_STAT stat;
13673 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010013674
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013675 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010013676 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013677#if USE_UNICODE_WCHAR_CACHE
13678_Py_COMP_DIAG_PUSH
13679_Py_COMP_DIAG_IGNORE_DEPR_DECLS
13680 const wchar_t *path = PyUnicode_AsUnicode(unicode);
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013681 result = LSTAT(path, &stat);
13682 Py_DECREF(unicode);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013683_Py_COMP_DIAG_POP
13684#else /* USE_UNICODE_WCHAR_CACHE */
13685 wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL);
13686 Py_DECREF(unicode);
13687 result = LSTAT(path, &stat);
13688 PyMem_Free(path);
13689#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013690
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013691 if (result != 0)
13692 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013693
13694 self->win32_file_index = stat.st_ino;
13695 self->got_file_index = 1;
13696 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013697 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13698 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013699#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013700 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13701 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013702#endif
13703}
13704
13705static PyObject *
13706DirEntry_repr(DirEntry *self)
13707{
13708 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13709}
13710
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013711/*[clinic input]
13712os.DirEntry.__fspath__
13713
13714Returns the path for the entry.
13715[clinic start generated code]*/
13716
Brett Cannon96881cd2016-06-10 14:37:21 -070013717static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013718os_DirEntry___fspath___impl(DirEntry *self)
13719/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013720{
13721 Py_INCREF(self->path);
13722 return self->path;
13723}
13724
Victor Stinner6036e442015-03-08 01:58:04 +010013725static PyMemberDef DirEntry_members[] = {
13726 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13727 "the entry's base filename, relative to scandir() \"path\" argument"},
13728 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13729 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13730 {NULL}
13731};
13732
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013733#include "clinic/posixmodule.c.h"
13734
Victor Stinner6036e442015-03-08 01:58:04 +010013735static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013736 OS_DIRENTRY_IS_DIR_METHODDEF
13737 OS_DIRENTRY_IS_FILE_METHODDEF
13738 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13739 OS_DIRENTRY_STAT_METHODDEF
13740 OS_DIRENTRY_INODE_METHODDEF
13741 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013742 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13743 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013744 {NULL}
13745};
13746
Eddie Elizondob3966632019-11-05 07:16:14 -080013747static PyType_Slot DirEntryType_slots[] = {
13748 {Py_tp_new, _disabled_new},
13749 {Py_tp_dealloc, DirEntry_dealloc},
13750 {Py_tp_repr, DirEntry_repr},
13751 {Py_tp_methods, DirEntry_methods},
13752 {Py_tp_members, DirEntry_members},
13753 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013754};
13755
Eddie Elizondob3966632019-11-05 07:16:14 -080013756static PyType_Spec DirEntryType_spec = {
13757 MODNAME ".DirEntry",
13758 sizeof(DirEntry),
13759 0,
13760 Py_TPFLAGS_DEFAULT,
13761 DirEntryType_slots
13762};
13763
13764
Victor Stinner6036e442015-03-08 01:58:04 +010013765#ifdef MS_WINDOWS
13766
13767static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013768join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013769{
13770 Py_ssize_t path_len;
13771 Py_ssize_t size;
13772 wchar_t *result;
13773 wchar_t ch;
13774
13775 if (!path_wide) { /* Default arg: "." */
13776 path_wide = L".";
13777 path_len = 1;
13778 }
13779 else {
13780 path_len = wcslen(path_wide);
13781 }
13782
13783 /* The +1's are for the path separator and the NUL */
13784 size = path_len + 1 + wcslen(filename) + 1;
13785 result = PyMem_New(wchar_t, size);
13786 if (!result) {
13787 PyErr_NoMemory();
13788 return NULL;
13789 }
13790 wcscpy(result, path_wide);
13791 if (path_len > 0) {
13792 ch = result[path_len - 1];
13793 if (ch != SEP && ch != ALTSEP && ch != L':')
13794 result[path_len++] = SEP;
13795 wcscpy(result + path_len, filename);
13796 }
13797 return result;
13798}
13799
13800static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013801DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013802{
13803 DirEntry *entry;
13804 BY_HANDLE_FILE_INFORMATION file_info;
13805 ULONG reparse_tag;
13806 wchar_t *joined_path;
13807
Victor Stinner1c2fa782020-05-10 11:05:29 +020013808 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013809 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013810 if (!entry)
13811 return NULL;
13812 entry->name = NULL;
13813 entry->path = NULL;
13814 entry->stat = NULL;
13815 entry->lstat = NULL;
13816 entry->got_file_index = 0;
13817
13818 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13819 if (!entry->name)
13820 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013821 if (path->narrow) {
13822 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13823 if (!entry->name)
13824 goto error;
13825 }
Victor Stinner6036e442015-03-08 01:58:04 +010013826
13827 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13828 if (!joined_path)
13829 goto error;
13830
13831 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13832 PyMem_Free(joined_path);
13833 if (!entry->path)
13834 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013835 if (path->narrow) {
13836 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13837 if (!entry->path)
13838 goto error;
13839 }
Victor Stinner6036e442015-03-08 01:58:04 +010013840
Steve Dowercc16be82016-09-08 10:35:16 -070013841 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013842 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13843
13844 return (PyObject *)entry;
13845
13846error:
13847 Py_DECREF(entry);
13848 return NULL;
13849}
13850
13851#else /* POSIX */
13852
13853static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013854join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013855{
13856 Py_ssize_t path_len;
13857 Py_ssize_t size;
13858 char *result;
13859
13860 if (!path_narrow) { /* Default arg: "." */
13861 path_narrow = ".";
13862 path_len = 1;
13863 }
13864 else {
13865 path_len = strlen(path_narrow);
13866 }
13867
13868 if (filename_len == -1)
13869 filename_len = strlen(filename);
13870
13871 /* The +1's are for the path separator and the NUL */
13872 size = path_len + 1 + filename_len + 1;
13873 result = PyMem_New(char, size);
13874 if (!result) {
13875 PyErr_NoMemory();
13876 return NULL;
13877 }
13878 strcpy(result, path_narrow);
13879 if (path_len > 0 && result[path_len - 1] != '/')
13880 result[path_len++] = '/';
13881 strcpy(result + path_len, filename);
13882 return result;
13883}
13884
13885static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013886DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13887 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013888#ifdef HAVE_DIRENT_D_TYPE
13889 , unsigned char d_type
13890#endif
13891 )
Victor Stinner6036e442015-03-08 01:58:04 +010013892{
13893 DirEntry *entry;
13894 char *joined_path;
13895
Victor Stinner1c2fa782020-05-10 11:05:29 +020013896 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013897 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013898 if (!entry)
13899 return NULL;
13900 entry->name = NULL;
13901 entry->path = NULL;
13902 entry->stat = NULL;
13903 entry->lstat = NULL;
13904
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013905 if (path->fd != -1) {
13906 entry->dir_fd = path->fd;
13907 joined_path = NULL;
13908 }
13909 else {
13910 entry->dir_fd = DEFAULT_DIR_FD;
13911 joined_path = join_path_filename(path->narrow, name, name_len);
13912 if (!joined_path)
13913 goto error;
13914 }
Victor Stinner6036e442015-03-08 01:58:04 +010013915
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013916 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013917 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013918 if (joined_path)
13919 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013920 }
13921 else {
13922 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013923 if (joined_path)
13924 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013925 }
13926 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013927 if (!entry->name)
13928 goto error;
13929
13930 if (path->fd != -1) {
13931 entry->path = entry->name;
13932 Py_INCREF(entry->path);
13933 }
13934 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013935 goto error;
13936
Victor Stinner35a97c02015-03-08 02:59:09 +010013937#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013938 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013939#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013940 entry->d_ino = d_ino;
13941
13942 return (PyObject *)entry;
13943
13944error:
13945 Py_XDECREF(entry);
13946 return NULL;
13947}
13948
13949#endif
13950
13951
13952typedef struct {
13953 PyObject_HEAD
13954 path_t path;
13955#ifdef MS_WINDOWS
13956 HANDLE handle;
13957 WIN32_FIND_DATAW file_data;
13958 int first_time;
13959#else /* POSIX */
13960 DIR *dirp;
13961#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013962#ifdef HAVE_FDOPENDIR
13963 int fd;
13964#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013965} ScandirIterator;
13966
13967#ifdef MS_WINDOWS
13968
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013969static int
13970ScandirIterator_is_closed(ScandirIterator *iterator)
13971{
13972 return iterator->handle == INVALID_HANDLE_VALUE;
13973}
13974
Victor Stinner6036e442015-03-08 01:58:04 +010013975static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013976ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013977{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013978 HANDLE handle = iterator->handle;
13979
13980 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013981 return;
13982
Victor Stinner6036e442015-03-08 01:58:04 +010013983 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013984 Py_BEGIN_ALLOW_THREADS
13985 FindClose(handle);
13986 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013987}
13988
13989static PyObject *
13990ScandirIterator_iternext(ScandirIterator *iterator)
13991{
13992 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13993 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013994 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013995
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013996 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013997 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013998 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013999
14000 while (1) {
14001 if (!iterator->first_time) {
14002 Py_BEGIN_ALLOW_THREADS
14003 success = FindNextFileW(iterator->handle, file_data);
14004 Py_END_ALLOW_THREADS
14005 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014006 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010014007 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014008 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010014009 break;
14010 }
14011 }
14012 iterator->first_time = 0;
14013
14014 /* Skip over . and .. */
14015 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020014016 wcscmp(file_data->cFileName, L"..") != 0)
14017 {
14018 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
14019 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014020 if (!entry)
14021 break;
14022 return entry;
14023 }
Victor Stinner6036e442015-03-08 01:58:04 +010014024
14025 /* Loop till we get a non-dot directory or finish iterating */
14026 }
14027
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014028 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014029 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010014030 return NULL;
14031}
14032
14033#else /* POSIX */
14034
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014035static int
14036ScandirIterator_is_closed(ScandirIterator *iterator)
14037{
14038 return !iterator->dirp;
14039}
14040
Victor Stinner6036e442015-03-08 01:58:04 +010014041static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014042ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010014043{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014044 DIR *dirp = iterator->dirp;
14045
14046 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010014047 return;
14048
Victor Stinner6036e442015-03-08 01:58:04 +010014049 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014050 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014051#ifdef HAVE_FDOPENDIR
14052 if (iterator->path.fd != -1)
14053 rewinddir(dirp);
14054#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014055 closedir(dirp);
14056 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010014057 return;
14058}
14059
14060static PyObject *
14061ScandirIterator_iternext(ScandirIterator *iterator)
14062{
14063 struct dirent *direntp;
14064 Py_ssize_t name_len;
14065 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014066 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014067
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014068 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014069 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010014070 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014071
14072 while (1) {
14073 errno = 0;
14074 Py_BEGIN_ALLOW_THREADS
14075 direntp = readdir(iterator->dirp);
14076 Py_END_ALLOW_THREADS
14077
14078 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014079 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010014080 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014081 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010014082 break;
14083 }
14084
14085 /* Skip over . and .. */
14086 name_len = NAMLEN(direntp);
14087 is_dot = direntp->d_name[0] == '.' &&
14088 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
14089 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014090 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
14091 entry = DirEntry_from_posix_info(module,
14092 &iterator->path, direntp->d_name,
14093 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010014094#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020014095 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010014096#endif
14097 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014098 if (!entry)
14099 break;
14100 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014101 }
14102
14103 /* Loop till we get a non-dot directory or finish iterating */
14104 }
14105
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014106 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014107 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010014108 return NULL;
14109}
14110
14111#endif
14112
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014113static PyObject *
14114ScandirIterator_close(ScandirIterator *self, PyObject *args)
14115{
14116 ScandirIterator_closedir(self);
14117 Py_RETURN_NONE;
14118}
14119
14120static PyObject *
14121ScandirIterator_enter(PyObject *self, PyObject *args)
14122{
14123 Py_INCREF(self);
14124 return self;
14125}
14126
14127static PyObject *
14128ScandirIterator_exit(ScandirIterator *self, PyObject *args)
14129{
14130 ScandirIterator_closedir(self);
14131 Py_RETURN_NONE;
14132}
14133
Victor Stinner6036e442015-03-08 01:58:04 +010014134static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010014135ScandirIterator_finalize(ScandirIterator *iterator)
14136{
14137 PyObject *error_type, *error_value, *error_traceback;
14138
14139 /* Save the current exception, if any. */
14140 PyErr_Fetch(&error_type, &error_value, &error_traceback);
14141
14142 if (!ScandirIterator_is_closed(iterator)) {
14143 ScandirIterator_closedir(iterator);
14144
14145 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
14146 "unclosed scandir iterator %R", iterator)) {
14147 /* Spurious errors can appear at shutdown */
14148 if (PyErr_ExceptionMatches(PyExc_Warning)) {
14149 PyErr_WriteUnraisable((PyObject *) iterator);
14150 }
14151 }
14152 }
14153
Victor Stinner7bfa4092016-03-23 00:43:54 +010014154 path_cleanup(&iterator->path);
14155
14156 /* Restore the saved exception. */
14157 PyErr_Restore(error_type, error_value, error_traceback);
14158}
14159
14160static void
Victor Stinner6036e442015-03-08 01:58:04 +010014161ScandirIterator_dealloc(ScandirIterator *iterator)
14162{
Eddie Elizondob3966632019-11-05 07:16:14 -080014163 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010014164 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
14165 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014166
Eddie Elizondob3966632019-11-05 07:16:14 -080014167 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
14168 free_func(iterator);
14169 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010014170}
14171
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014172static PyMethodDef ScandirIterator_methods[] = {
14173 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
14174 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
14175 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
14176 {NULL}
14177};
14178
Eddie Elizondob3966632019-11-05 07:16:14 -080014179static PyType_Slot ScandirIteratorType_slots[] = {
14180 {Py_tp_new, _disabled_new},
14181 {Py_tp_dealloc, ScandirIterator_dealloc},
14182 {Py_tp_finalize, ScandirIterator_finalize},
14183 {Py_tp_iter, PyObject_SelfIter},
14184 {Py_tp_iternext, ScandirIterator_iternext},
14185 {Py_tp_methods, ScandirIterator_methods},
14186 {0, 0},
14187};
14188
14189static PyType_Spec ScandirIteratorType_spec = {
14190 MODNAME ".ScandirIterator",
14191 sizeof(ScandirIterator),
14192 0,
Victor Stinner97f33c32020-05-14 18:05:58 +020014193 // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
14194 // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
Eddie Elizondob3966632019-11-05 07:16:14 -080014195 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
14196 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010014197};
14198
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014199/*[clinic input]
14200os.scandir
14201
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014202 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014203
14204Return an iterator of DirEntry objects for given path.
14205
BNMetricsb9427072018-11-02 15:20:19 +000014206path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014207is bytes, the names of yielded DirEntry objects will also be bytes; in
14208all other circumstances they will be str.
14209
14210If path is None, uses the path='.'.
14211[clinic start generated code]*/
14212
Victor Stinner6036e442015-03-08 01:58:04 +010014213static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014214os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000014215/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010014216{
14217 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010014218#ifdef MS_WINDOWS
14219 wchar_t *path_strW;
14220#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014221 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014222#ifdef HAVE_FDOPENDIR
14223 int fd = -1;
14224#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014225#endif
14226
Steve Dower60419a72019-06-24 08:42:54 -070014227 if (PySys_Audit("os.scandir", "O",
14228 path->object ? path->object : Py_None) < 0) {
14229 return NULL;
14230 }
14231
Hai Shif707d942020-03-16 21:15:01 +080014232 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014233 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010014234 if (!iterator)
14235 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014236
14237#ifdef MS_WINDOWS
14238 iterator->handle = INVALID_HANDLE_VALUE;
14239#else
14240 iterator->dirp = NULL;
14241#endif
14242
Serhiy Storchaka095ef732017-02-09 20:05:51 +020014243 /* Move the ownership to iterator->path */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014244 memcpy(&iterator->path, path, sizeof(path_t));
14245 memset(path, 0, sizeof(path_t));
Victor Stinner6036e442015-03-08 01:58:04 +010014246
14247#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010014248 iterator->first_time = 1;
14249
14250 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
14251 if (!path_strW)
14252 goto error;
14253
14254 Py_BEGIN_ALLOW_THREADS
14255 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
14256 Py_END_ALLOW_THREADS
14257
14258 PyMem_Free(path_strW);
14259
14260 if (iterator->handle == INVALID_HANDLE_VALUE) {
14261 path_error(&iterator->path);
14262 goto error;
14263 }
14264#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010014265 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014266#ifdef HAVE_FDOPENDIR
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014267 if (iterator->path.fd != -1) {
Ronald Oussoren41761932020-11-08 10:05:27 +010014268 if (HAVE_FDOPENDIR_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014269 /* closedir() closes the FD, so we duplicate it */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014270 fd = _Py_dup(iterator->path.fd);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014271 if (fd == -1)
14272 goto error;
14273
14274 Py_BEGIN_ALLOW_THREADS
14275 iterator->dirp = fdopendir(fd);
14276 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +010014277 } else {
14278 PyErr_SetString(PyExc_TypeError,
14279 "scandir: path should be string, bytes, os.PathLike or None, not int");
14280 return NULL;
14281 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014282 }
14283 else
14284#endif
14285 {
14286 if (iterator->path.narrow)
14287 path_str = iterator->path.narrow;
14288 else
14289 path_str = ".";
14290
14291 Py_BEGIN_ALLOW_THREADS
14292 iterator->dirp = opendir(path_str);
14293 Py_END_ALLOW_THREADS
14294 }
Victor Stinner6036e442015-03-08 01:58:04 +010014295
14296 if (!iterator->dirp) {
14297 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014298#ifdef HAVE_FDOPENDIR
14299 if (fd != -1) {
14300 Py_BEGIN_ALLOW_THREADS
14301 close(fd);
14302 Py_END_ALLOW_THREADS
14303 }
14304#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014305 goto error;
14306 }
14307#endif
14308
14309 return (PyObject *)iterator;
14310
14311error:
14312 Py_DECREF(iterator);
14313 return NULL;
14314}
14315
Ethan Furman410ef8e2016-06-04 12:06:26 -070014316/*
14317 Return the file system path representation of the object.
14318
14319 If the object is str or bytes, then allow it to pass through with
14320 an incremented refcount. If the object defines __fspath__(), then
14321 return the result of that method. All other types raise a TypeError.
14322*/
14323PyObject *
14324PyOS_FSPath(PyObject *path)
14325{
Brett Cannon3f9183b2016-08-26 14:44:48 -070014326 /* For error message reasons, this function is manually inlined in
14327 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070014328 PyObject *func = NULL;
14329 PyObject *path_repr = NULL;
14330
14331 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
14332 Py_INCREF(path);
14333 return path;
14334 }
14335
14336 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
14337 if (NULL == func) {
14338 return PyErr_Format(PyExc_TypeError,
14339 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014340 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080014341 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070014342 }
14343
Victor Stinnerf17c3de2016-12-06 18:46:19 +010014344 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070014345 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070014346 if (NULL == path_repr) {
14347 return NULL;
14348 }
14349
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014350 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
14351 PyErr_Format(PyExc_TypeError,
14352 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080014353 "not %.200s", _PyType_Name(Py_TYPE(path)),
14354 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014355 Py_DECREF(path_repr);
14356 return NULL;
14357 }
14358
Ethan Furman410ef8e2016-06-04 12:06:26 -070014359 return path_repr;
14360}
14361
14362/*[clinic input]
14363os.fspath
14364
14365 path: object
14366
14367Return the file system path representation of the object.
14368
Brett Cannonb4f43e92016-06-09 14:32:08 -070014369If the object is str or bytes, then allow it to pass through as-is. If the
14370object defines __fspath__(), then return the result of that method. All other
14371types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070014372[clinic start generated code]*/
14373
14374static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030014375os_fspath_impl(PyObject *module, PyObject *path)
14376/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070014377{
14378 return PyOS_FSPath(path);
14379}
Victor Stinner6036e442015-03-08 01:58:04 +010014380
Victor Stinner9b1f4742016-09-06 16:18:52 -070014381#ifdef HAVE_GETRANDOM_SYSCALL
14382/*[clinic input]
14383os.getrandom
14384
14385 size: Py_ssize_t
14386 flags: int=0
14387
14388Obtain a series of random bytes.
14389[clinic start generated code]*/
14390
14391static PyObject *
14392os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
14393/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
14394{
Victor Stinner9b1f4742016-09-06 16:18:52 -070014395 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014396 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014397
14398 if (size < 0) {
14399 errno = EINVAL;
14400 return posix_error();
14401 }
14402
Victor Stinnerec2319c2016-09-20 23:00:59 +020014403 bytes = PyBytes_FromStringAndSize(NULL, size);
14404 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014405 PyErr_NoMemory();
14406 return NULL;
14407 }
14408
14409 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014410 n = syscall(SYS_getrandom,
14411 PyBytes_AS_STRING(bytes),
14412 PyBytes_GET_SIZE(bytes),
14413 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070014414 if (n < 0 && errno == EINTR) {
14415 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014416 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014417 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020014418
14419 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070014420 continue;
14421 }
14422 break;
14423 }
14424
14425 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014426 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020014427 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014428 }
14429
Victor Stinnerec2319c2016-09-20 23:00:59 +020014430 if (n != size) {
14431 _PyBytes_Resize(&bytes, n);
14432 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070014433
14434 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014435
14436error:
14437 Py_DECREF(bytes);
14438 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014439}
14440#endif /* HAVE_GETRANDOM_SYSCALL */
14441
Steve Dower2438cdf2019-03-29 16:37:16 -070014442#ifdef MS_WINDOWS
14443/* bpo-36085: Helper functions for managing DLL search directories
14444 * on win32
14445 */
14446
14447typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
14448typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
14449
14450/*[clinic input]
14451os._add_dll_directory
14452
14453 path: path_t
14454
14455Add a path to the DLL search path.
14456
14457This search path is used when resolving dependencies for imported
14458extension modules (the module itself is resolved through sys.path),
14459and also by ctypes.
14460
14461Returns an opaque value that may be passed to os.remove_dll_directory
14462to remove this directory from the search path.
14463[clinic start generated code]*/
14464
14465static PyObject *
14466os__add_dll_directory_impl(PyObject *module, path_t *path)
14467/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
14468{
14469 HMODULE hKernel32;
14470 PAddDllDirectory AddDllDirectory;
14471 DLL_DIRECTORY_COOKIE cookie = 0;
14472 DWORD err = 0;
14473
Saiyang Gou7514f4f2020-02-12 23:47:42 -080014474 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
14475 return NULL;
14476 }
14477
Steve Dower2438cdf2019-03-29 16:37:16 -070014478 /* For Windows 7, we have to load this. As this will be a fairly
14479 infrequent operation, just do it each time. Kernel32 is always
14480 loaded. */
14481 Py_BEGIN_ALLOW_THREADS
14482 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14483 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
14484 hKernel32, "AddDllDirectory")) ||
14485 !(cookie = (*AddDllDirectory)(path->wide))) {
14486 err = GetLastError();
14487 }
14488 Py_END_ALLOW_THREADS
14489
14490 if (err) {
14491 return win32_error_object_err("add_dll_directory",
14492 path->object, err);
14493 }
14494
14495 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
14496}
14497
14498/*[clinic input]
14499os._remove_dll_directory
14500
14501 cookie: object
14502
14503Removes a path from the DLL search path.
14504
14505The parameter is an opaque value that was returned from
14506os.add_dll_directory. You can only remove directories that you added
14507yourself.
14508[clinic start generated code]*/
14509
14510static PyObject *
14511os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
14512/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
14513{
14514 HMODULE hKernel32;
14515 PRemoveDllDirectory RemoveDllDirectory;
14516 DLL_DIRECTORY_COOKIE cookieValue;
14517 DWORD err = 0;
14518
14519 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
14520 PyErr_SetString(PyExc_TypeError,
14521 "Provided cookie was not returned from os.add_dll_directory");
14522 return NULL;
14523 }
14524
14525 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
14526 cookie, "DLL directory cookie");
14527
14528 /* For Windows 7, we have to load this. As this will be a fairly
14529 infrequent operation, just do it each time. Kernel32 is always
14530 loaded. */
14531 Py_BEGIN_ALLOW_THREADS
14532 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14533 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
14534 hKernel32, "RemoveDllDirectory")) ||
14535 !(*RemoveDllDirectory)(cookieValue)) {
14536 err = GetLastError();
14537 }
14538 Py_END_ALLOW_THREADS
14539
14540 if (err) {
14541 return win32_error_object_err("remove_dll_directory",
14542 NULL, err);
14543 }
14544
14545 if (PyCapsule_SetName(cookie, NULL)) {
14546 return NULL;
14547 }
14548
14549 Py_RETURN_NONE;
14550}
14551
14552#endif
Larry Hastings31826802013-10-19 00:09:25 -070014553
Victor Stinner65a796e2020-04-01 18:49:29 +020014554
14555/* Only check if WIFEXITED is available: expect that it comes
14556 with WEXITSTATUS, WIFSIGNALED, etc.
14557
14558 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
14559 subprocess can safely call it during late Python finalization without
Victor Stinner62230712020-11-18 23:18:29 +010014560 risking that used os attributes were set to None by finalize_modules(). */
Victor Stinner65a796e2020-04-01 18:49:29 +020014561#if defined(WIFEXITED) || defined(MS_WINDOWS)
14562/*[clinic input]
14563os.waitstatus_to_exitcode
14564
Victor Stinner9bee32b2020-04-22 16:30:35 +020014565 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020014566
14567Convert a wait status to an exit code.
14568
14569On Unix:
14570
14571* If WIFEXITED(status) is true, return WEXITSTATUS(status).
14572* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
14573* Otherwise, raise a ValueError.
14574
14575On Windows, return status shifted right by 8 bits.
14576
14577On Unix, if the process is being traced or if waitpid() was called with
14578WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
14579This function must not be called if WIFSTOPPED(status) is true.
14580[clinic start generated code]*/
14581
14582static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020014583os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
14584/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020014585{
14586#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020014587 int status = _PyLong_AsInt(status_obj);
14588 if (status == -1 && PyErr_Occurred()) {
14589 return NULL;
14590 }
14591
Victor Stinner65a796e2020-04-01 18:49:29 +020014592 WAIT_TYPE wait_status;
14593 WAIT_STATUS_INT(wait_status) = status;
14594 int exitcode;
14595 if (WIFEXITED(wait_status)) {
14596 exitcode = WEXITSTATUS(wait_status);
14597 /* Sanity check to provide warranty on the function behavior.
14598 It should not occur in practice */
14599 if (exitcode < 0) {
14600 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
14601 return NULL;
14602 }
14603 }
14604 else if (WIFSIGNALED(wait_status)) {
14605 int signum = WTERMSIG(wait_status);
14606 /* Sanity check to provide warranty on the function behavior.
14607 It should not occurs in practice */
14608 if (signum <= 0) {
14609 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
14610 return NULL;
14611 }
14612 exitcode = -signum;
14613 } else if (WIFSTOPPED(wait_status)) {
14614 /* Status only received if the process is being traced
14615 or if waitpid() was called with WUNTRACED option. */
14616 int signum = WSTOPSIG(wait_status);
14617 PyErr_Format(PyExc_ValueError,
14618 "process stopped by delivery of signal %i",
14619 signum);
14620 return NULL;
14621 }
14622 else {
14623 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
14624 return NULL;
14625 }
14626 return PyLong_FromLong(exitcode);
14627#else
14628 /* Windows implementation: see os.waitpid() implementation
14629 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020014630 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
14631 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
14632 return NULL;
14633 }
14634
14635 unsigned long long exitcode = (status >> 8);
14636 /* ExitProcess() accepts an UINT type:
14637 reject exit code which doesn't fit in an UINT */
14638 if (exitcode > UINT_MAX) {
14639 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
14640 return NULL;
14641 }
14642 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020014643#endif
14644}
14645#endif
14646
14647
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014648static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070014649
14650 OS_STAT_METHODDEF
14651 OS_ACCESS_METHODDEF
14652 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014653 OS_CHDIR_METHODDEF
14654 OS_CHFLAGS_METHODDEF
14655 OS_CHMOD_METHODDEF
14656 OS_FCHMOD_METHODDEF
14657 OS_LCHMOD_METHODDEF
14658 OS_CHOWN_METHODDEF
14659 OS_FCHOWN_METHODDEF
14660 OS_LCHOWN_METHODDEF
14661 OS_LCHFLAGS_METHODDEF
14662 OS_CHROOT_METHODDEF
14663 OS_CTERMID_METHODDEF
14664 OS_GETCWD_METHODDEF
14665 OS_GETCWDB_METHODDEF
14666 OS_LINK_METHODDEF
14667 OS_LISTDIR_METHODDEF
14668 OS_LSTAT_METHODDEF
14669 OS_MKDIR_METHODDEF
14670 OS_NICE_METHODDEF
14671 OS_GETPRIORITY_METHODDEF
14672 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014673 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030014674 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014675 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010014676 OS_COPY_FILE_RANGE_METHODDEF
Pablo Galindoa57b3d32020-11-17 00:00:38 +000014677 OS_SPLICE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014678 OS_RENAME_METHODDEF
14679 OS_REPLACE_METHODDEF
14680 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014681 OS_SYMLINK_METHODDEF
14682 OS_SYSTEM_METHODDEF
14683 OS_UMASK_METHODDEF
14684 OS_UNAME_METHODDEF
14685 OS_UNLINK_METHODDEF
14686 OS_REMOVE_METHODDEF
14687 OS_UTIME_METHODDEF
14688 OS_TIMES_METHODDEF
14689 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014690 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014691 OS_EXECV_METHODDEF
14692 OS_EXECVE_METHODDEF
14693 OS_SPAWNV_METHODDEF
14694 OS_SPAWNVE_METHODDEF
14695 OS_FORK1_METHODDEF
14696 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014697 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014698 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14699 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14700 OS_SCHED_GETPARAM_METHODDEF
14701 OS_SCHED_GETSCHEDULER_METHODDEF
14702 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14703 OS_SCHED_SETPARAM_METHODDEF
14704 OS_SCHED_SETSCHEDULER_METHODDEF
14705 OS_SCHED_YIELD_METHODDEF
14706 OS_SCHED_SETAFFINITY_METHODDEF
14707 OS_SCHED_GETAFFINITY_METHODDEF
14708 OS_OPENPTY_METHODDEF
14709 OS_FORKPTY_METHODDEF
14710 OS_GETEGID_METHODDEF
14711 OS_GETEUID_METHODDEF
14712 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014713 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014714 OS_GETGROUPS_METHODDEF
14715 OS_GETPID_METHODDEF
14716 OS_GETPGRP_METHODDEF
14717 OS_GETPPID_METHODDEF
14718 OS_GETUID_METHODDEF
14719 OS_GETLOGIN_METHODDEF
14720 OS_KILL_METHODDEF
14721 OS_KILLPG_METHODDEF
14722 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014723 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014724 OS_SETUID_METHODDEF
14725 OS_SETEUID_METHODDEF
14726 OS_SETREUID_METHODDEF
14727 OS_SETGID_METHODDEF
14728 OS_SETEGID_METHODDEF
14729 OS_SETREGID_METHODDEF
14730 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014731 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014732 OS_GETPGID_METHODDEF
14733 OS_SETPGRP_METHODDEF
14734 OS_WAIT_METHODDEF
14735 OS_WAIT3_METHODDEF
14736 OS_WAIT4_METHODDEF
14737 OS_WAITID_METHODDEF
14738 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014739 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014740 OS_GETSID_METHODDEF
14741 OS_SETSID_METHODDEF
14742 OS_SETPGID_METHODDEF
14743 OS_TCGETPGRP_METHODDEF
14744 OS_TCSETPGRP_METHODDEF
14745 OS_OPEN_METHODDEF
14746 OS_CLOSE_METHODDEF
14747 OS_CLOSERANGE_METHODDEF
14748 OS_DEVICE_ENCODING_METHODDEF
14749 OS_DUP_METHODDEF
14750 OS_DUP2_METHODDEF
14751 OS_LOCKF_METHODDEF
14752 OS_LSEEK_METHODDEF
14753 OS_READ_METHODDEF
14754 OS_READV_METHODDEF
14755 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014756 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014757 OS_WRITE_METHODDEF
14758 OS_WRITEV_METHODDEF
14759 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014760 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014761 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014762 OS_FSTAT_METHODDEF
14763 OS_ISATTY_METHODDEF
14764 OS_PIPE_METHODDEF
14765 OS_PIPE2_METHODDEF
14766 OS_MKFIFO_METHODDEF
14767 OS_MKNOD_METHODDEF
14768 OS_MAJOR_METHODDEF
14769 OS_MINOR_METHODDEF
14770 OS_MAKEDEV_METHODDEF
14771 OS_FTRUNCATE_METHODDEF
14772 OS_TRUNCATE_METHODDEF
14773 OS_POSIX_FALLOCATE_METHODDEF
14774 OS_POSIX_FADVISE_METHODDEF
14775 OS_PUTENV_METHODDEF
14776 OS_UNSETENV_METHODDEF
14777 OS_STRERROR_METHODDEF
14778 OS_FCHDIR_METHODDEF
14779 OS_FSYNC_METHODDEF
14780 OS_SYNC_METHODDEF
14781 OS_FDATASYNC_METHODDEF
14782 OS_WCOREDUMP_METHODDEF
14783 OS_WIFCONTINUED_METHODDEF
14784 OS_WIFSTOPPED_METHODDEF
14785 OS_WIFSIGNALED_METHODDEF
14786 OS_WIFEXITED_METHODDEF
14787 OS_WEXITSTATUS_METHODDEF
14788 OS_WTERMSIG_METHODDEF
14789 OS_WSTOPSIG_METHODDEF
14790 OS_FSTATVFS_METHODDEF
14791 OS_STATVFS_METHODDEF
14792 OS_CONFSTR_METHODDEF
14793 OS_SYSCONF_METHODDEF
14794 OS_FPATHCONF_METHODDEF
14795 OS_PATHCONF_METHODDEF
14796 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014797 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014798 OS__GETDISKUSAGE_METHODDEF
14799 OS__GETFINALPATHNAME_METHODDEF
14800 OS__GETVOLUMEPATHNAME_METHODDEF
Steve Dower04732ca2021-04-07 01:02:07 +010014801 OS__PATH_SPLITROOT_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014802 OS_GETLOADAVG_METHODDEF
14803 OS_URANDOM_METHODDEF
14804 OS_SETRESUID_METHODDEF
14805 OS_SETRESGID_METHODDEF
14806 OS_GETRESUID_METHODDEF
14807 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014808
Larry Hastings2f936352014-08-05 14:04:04 +100014809 OS_GETXATTR_METHODDEF
14810 OS_SETXATTR_METHODDEF
14811 OS_REMOVEXATTR_METHODDEF
14812 OS_LISTXATTR_METHODDEF
14813
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014814 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014815 OS_CPU_COUNT_METHODDEF
14816 OS_GET_INHERITABLE_METHODDEF
14817 OS_SET_INHERITABLE_METHODDEF
14818 OS_GET_HANDLE_INHERITABLE_METHODDEF
14819 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014820 OS_GET_BLOCKING_METHODDEF
14821 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014822 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014823 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014824 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014825 OS_MEMFD_CREATE_METHODDEF
Christian Heimescd9fed62020-11-13 19:48:52 +010014826 OS_EVENTFD_METHODDEF
14827 OS_EVENTFD_READ_METHODDEF
14828 OS_EVENTFD_WRITE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014829 OS__ADD_DLL_DIRECTORY_METHODDEF
14830 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014831 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014832 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014833};
14834
Barry Warsaw4a342091996-12-19 23:50:02 +000014835static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014836all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014837{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014838#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014839 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014840#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014841#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014842 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014843#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014844#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014845 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014846#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014847#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014848 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014849#endif
Fred Drakec9680921999-12-13 16:37:25 +000014850#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014851 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014852#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014853#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014854 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014855#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014856#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014857 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014858#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014859#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014860 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014861#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014862#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014863 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014864#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014865#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014866 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014867#endif
14868#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014869 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014870#endif
14871#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014872 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014873#endif
14874#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014875 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014876#endif
14877#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014878 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014879#endif
14880#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014881 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014882#endif
14883#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014884 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014885#endif
14886#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014887 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014888#endif
14889#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014890 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014891#endif
14892#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014893 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014894#endif
14895#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014896 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014897#endif
14898#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014899 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014900#endif
14901#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014902 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014903#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014904#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014905 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014906#endif
14907#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014908 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014909#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014910#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014911 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014912#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014913#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014914 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014915#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014916#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014917#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014918 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014919#endif
14920#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014921 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014922#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014923#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014924#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014925 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014926#endif
14927#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014928 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014929#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014930#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014931 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014932#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014933#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014934 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014935#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014936#ifdef O_TMPFILE
14937 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14938#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014939#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014940 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014941#endif
14942#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014943 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014944#endif
14945#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014946 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014947#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014948#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014949 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014950#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014951#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014952 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014953#endif
Dong-hee Naf917c242021-02-04 08:32:55 +090014954#ifdef O_EVTONLY
14955 if (PyModule_AddIntMacro(m, O_EVTONLY)) return -1;
14956#endif
14957#ifdef O_FSYNC
14958 if (PyModule_AddIntMacro(m, O_FSYNC)) return -1;
14959#endif
14960#ifdef O_SYMLINK
14961 if (PyModule_AddIntMacro(m, O_SYMLINK)) return -1;
14962#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014963
Jesus Cea94363612012-06-22 18:32:07 +020014964#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014965 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014966#endif
14967#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014968 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014969#endif
14970
Tim Peters5aa91602002-01-30 05:46:57 +000014971/* MS Windows */
14972#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014973 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014974 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014975#endif
14976#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000014977 /* Optimize for short life (keep in memory). */
14978 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014979 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014980#endif
14981#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000014982 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014983 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014984#endif
14985#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000014986 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014987 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014988#endif
14989#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014990 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014991 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014992#endif
14993
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014994/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014995#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014996 /* Send a SIGIO signal whenever input or output
14997 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014998 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014999#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015000#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000015001 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015002 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015003#endif
15004#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000015005 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015006 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015007#endif
15008#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000015009 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015010 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000015011#endif
Dong-hee Naf917c242021-02-04 08:32:55 +090015012#ifdef O_NOFOLLOW_ANY
15013 if (PyModule_AddIntMacro(m, O_NOFOLLOW_ANY)) return -1;
15014#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020015015#ifdef O_NOLINKS
15016 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015017 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020015018#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000015019#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000015020 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015021 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000015022#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000015023
Victor Stinner8c62be82010-05-06 00:08:46 +000015024 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015025#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015026 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015027#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015028#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015029 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015030#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015031#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015032 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015033#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015034#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015035 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015036#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015037#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015038 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015039#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015040#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015041 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015042#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015043#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015044 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015045#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015046#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015047 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015048#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015049#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015050 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015051#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015052#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015053 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015054#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015055#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015056 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015057#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015058#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015059 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015060#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015061#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015062 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015063#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015064#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015065 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015066#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015067#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015068 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015069#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015070#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015071 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015072#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015073#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015074 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015075#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015076
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000015077 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015078#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015079 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015080#endif /* ST_RDONLY */
15081#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015082 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015083#endif /* ST_NOSUID */
15084
doko@ubuntu.comca616a22013-12-08 15:23:07 +010015085 /* GNU extensions */
15086#ifdef ST_NODEV
15087 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
15088#endif /* ST_NODEV */
15089#ifdef ST_NOEXEC
15090 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
15091#endif /* ST_NOEXEC */
15092#ifdef ST_SYNCHRONOUS
15093 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
15094#endif /* ST_SYNCHRONOUS */
15095#ifdef ST_MANDLOCK
15096 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
15097#endif /* ST_MANDLOCK */
15098#ifdef ST_WRITE
15099 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
15100#endif /* ST_WRITE */
15101#ifdef ST_APPEND
15102 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
15103#endif /* ST_APPEND */
15104#ifdef ST_NOATIME
15105 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
15106#endif /* ST_NOATIME */
15107#ifdef ST_NODIRATIME
15108 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
15109#endif /* ST_NODIRATIME */
15110#ifdef ST_RELATIME
15111 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
15112#endif /* ST_RELATIME */
15113
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015114 /* FreeBSD sendfile() constants */
15115#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015116 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015117#endif
15118#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015119 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015120#endif
15121#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015122 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015123#endif
15124
Ross Lagerwall7807c352011-03-17 20:20:30 +020015125 /* constants for posix_fadvise */
15126#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015127 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015128#endif
15129#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015130 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015131#endif
15132#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015133 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015134#endif
15135#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015136 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015137#endif
15138#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015139 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015140#endif
15141#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015142 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015143#endif
15144
15145 /* constants for waitid */
15146#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015147 if (PyModule_AddIntMacro(m, P_PID)) return -1;
15148 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
15149 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080015150#ifdef P_PIDFD
15151 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
15152#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015153#endif
15154#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015155 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015156#endif
15157#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015158 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015159#endif
15160#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015161 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015162#endif
15163#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015164 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015165#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015166#ifdef CLD_KILLED
15167 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
15168#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015169#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015170 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015171#endif
15172#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015173 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015174#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015175#ifdef CLD_STOPPED
15176 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
15177#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015178#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015179 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015180#endif
15181
15182 /* constants for lockf */
15183#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015184 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015185#endif
15186#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015187 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015188#endif
15189#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015190 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015191#endif
15192#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015193 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015194#endif
15195
Pablo Galindo4defba32018-01-27 16:16:37 +000015196#ifdef RWF_DSYNC
15197 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
15198#endif
15199#ifdef RWF_HIPRI
15200 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
15201#endif
15202#ifdef RWF_SYNC
15203 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
15204#endif
15205#ifdef RWF_NOWAIT
15206 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
15207#endif
YoSTEALTH76ef2552020-05-27 15:32:22 -060015208#ifdef RWF_APPEND
15209 if (PyModule_AddIntConstant(m, "RWF_APPEND", RWF_APPEND)) return -1;
15210#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000015211
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015212/* constants for splice */
Pablo Galindo2a9eddf2020-11-17 19:57:49 +000015213#if defined(HAVE_SPLICE) && defined(__linux__)
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015214 if (PyModule_AddIntConstant(m, "SPLICE_F_MOVE", SPLICE_F_MOVE)) return -1;
15215 if (PyModule_AddIntConstant(m, "SPLICE_F_NONBLOCK", SPLICE_F_NONBLOCK)) return -1;
15216 if (PyModule_AddIntConstant(m, "SPLICE_F_MORE", SPLICE_F_MORE)) return -1;
15217#endif
15218
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000015219/* constants for posix_spawn */
15220#ifdef HAVE_POSIX_SPAWN
15221 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
15222 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
15223 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
15224#endif
15225
pxinwrf2d7ac72019-05-21 18:46:37 +080015226#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015227 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
15228 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015229 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080015230#endif
15231#ifdef HAVE_SPAWNV
15232 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015233 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000015234#endif
15235
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015236#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015237#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015238 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015239#endif
15240#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015241 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015242#endif
15243#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015244 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015245#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015246#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080015247 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015248#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015249#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015250 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015251#endif
15252#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015253 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015254#endif
15255#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015256 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015257#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015258#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015259 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015260#endif
15261#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015262 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015263#endif
15264#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015265 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015266#endif
15267#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015268 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015269#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015270#endif
15271
Benjamin Peterson9428d532011-09-14 11:45:52 -040015272#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015273 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
15274 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
15275 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015276#endif
15277
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015278#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015279 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015280#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015281#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015282 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015283#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015284#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015285 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015286#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015287#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015288 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015289#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015290#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015291 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015292#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015293#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015294 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015295#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015296#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015297 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015298#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010015299#if HAVE_DECL_RTLD_MEMBER
15300 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
15301#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020015302
Victor Stinner9b1f4742016-09-06 16:18:52 -070015303#ifdef HAVE_GETRANDOM_SYSCALL
15304 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
15305 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
15306#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015307#ifdef HAVE_MEMFD_CREATE
15308 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
15309 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
15310#ifdef MFD_HUGETLB
15311 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015312#endif
15313#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015314 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015315#endif
15316#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015317 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015318#endif
15319#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015320 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015321#endif
15322#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015323 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015324#endif
15325#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015326 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015327#endif
15328#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015329 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015330#endif
15331#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015332 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015333#endif
15334#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015335 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015336#endif
15337#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015338 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015339#endif
15340#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015341 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015342#endif
15343#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015344 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015345#endif
15346#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015347 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015348#endif
15349#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015350 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015351#endif
15352#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015353 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
15354#endif
Christian Heimescd9fed62020-11-13 19:48:52 +010015355#endif /* HAVE_MEMFD_CREATE */
15356
15357#ifdef HAVE_EVENTFD
15358 if (PyModule_AddIntMacro(m, EFD_CLOEXEC)) return -1;
15359 if (PyModule_AddIntMacro(m, EFD_NONBLOCK)) return -1;
15360 if (PyModule_AddIntMacro(m, EFD_SEMAPHORE)) return -1;
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015361#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070015362
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020015363#if defined(__APPLE__)
15364 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
15365#endif
15366
Steve Dower2438cdf2019-03-29 16:37:16 -070015367#ifdef MS_WINDOWS
15368 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
15369 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
15370 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
15371 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
15372 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
15373#endif
15374
Victor Stinner8c62be82010-05-06 00:08:46 +000015375 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000015376}
15377
15378
Ronald Oussoren41761932020-11-08 10:05:27 +010015379
15380#define PROBE(name, test) \
15381 static int name(void) \
15382 { \
15383 if (test) { \
15384 return 1; \
15385 } else { \
15386 return 0; \
15387 } \
15388 }
15389
15390#ifdef HAVE_FSTATAT
15391PROBE(probe_fstatat, HAVE_FSTATAT_RUNTIME)
15392#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070015393
15394#ifdef HAVE_FACCESSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015395PROBE(probe_faccessat, HAVE_FACCESSAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015396#endif
15397
15398#ifdef HAVE_FCHMODAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015399PROBE(probe_fchmodat, HAVE_FCHMODAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015400#endif
15401
Larry Hastings00964ed2013-08-12 13:49:30 -040015402#ifdef HAVE_FCHOWNAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015403PROBE(probe_fchownat, HAVE_FCHOWNAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015404#endif
15405
15406#ifdef HAVE_LINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015407PROBE(probe_linkat, HAVE_LINKAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015408#endif
15409
Ronald Oussoren41761932020-11-08 10:05:27 +010015410#ifdef HAVE_FDOPENDIR
15411PROBE(probe_fdopendir, HAVE_FDOPENDIR_RUNTIME)
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015412#endif
15413
Larry Hastings9cf065c2012-06-22 16:30:09 -070015414#ifdef HAVE_MKDIRAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015415PROBE(probe_mkdirat, HAVE_MKDIRAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015416#endif
15417
15418#ifdef HAVE_RENAMEAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015419PROBE(probe_renameat, HAVE_RENAMEAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015420#endif
15421
15422#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015423PROBE(probe_unlinkat, HAVE_UNLINKAT_RUNTIME)
15424#endif
15425
15426#ifdef HAVE_OPENAT
15427PROBE(probe_openat, HAVE_OPENAT_RUNTIME)
15428#endif
15429
15430#ifdef HAVE_READLINKAT
15431PROBE(probe_readlinkat, HAVE_READLINKAT_RUNTIME)
15432#endif
15433
15434#ifdef HAVE_SYMLINKAT
15435PROBE(probe_symlinkat, HAVE_SYMLINKAT_RUNTIME)
15436#endif
15437
15438#ifdef HAVE_FUTIMENS
15439PROBE(probe_futimens, HAVE_FUTIMENS_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015440#endif
15441
15442#ifdef HAVE_UTIMENSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015443PROBE(probe_utimensat, HAVE_UTIMENSAT_RUNTIME)
15444#endif
15445
15446
15447
15448
15449static const struct have_function {
15450 const char * const label;
15451 int (*probe)(void);
15452} have_functions[] = {
15453
Christian Heimescd9fed62020-11-13 19:48:52 +010015454#ifdef HAVE_EVENTFD
15455 {"HAVE_EVENTFD", NULL},
15456#endif
15457
Ronald Oussoren41761932020-11-08 10:05:27 +010015458#ifdef HAVE_FACCESSAT
15459 { "HAVE_FACCESSAT", probe_faccessat },
15460#endif
15461
15462#ifdef HAVE_FCHDIR
15463 { "HAVE_FCHDIR", NULL },
15464#endif
15465
15466#ifdef HAVE_FCHMOD
15467 { "HAVE_FCHMOD", NULL },
15468#endif
15469
15470#ifdef HAVE_FCHMODAT
15471 { "HAVE_FCHMODAT", probe_fchmodat },
15472#endif
15473
15474#ifdef HAVE_FCHOWN
15475 { "HAVE_FCHOWN", NULL },
15476#endif
15477
15478#ifdef HAVE_FCHOWNAT
15479 { "HAVE_FCHOWNAT", probe_fchownat },
15480#endif
15481
15482#ifdef HAVE_FEXECVE
15483 { "HAVE_FEXECVE", NULL },
15484#endif
15485
15486#ifdef HAVE_FDOPENDIR
15487 { "HAVE_FDOPENDIR", probe_fdopendir },
15488#endif
15489
15490#ifdef HAVE_FPATHCONF
15491 { "HAVE_FPATHCONF", NULL },
15492#endif
15493
15494#ifdef HAVE_FSTATAT
15495 { "HAVE_FSTATAT", probe_fstatat },
15496#endif
15497
15498#ifdef HAVE_FSTATVFS
15499 { "HAVE_FSTATVFS", NULL },
15500#endif
15501
15502#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
15503 { "HAVE_FTRUNCATE", NULL },
15504#endif
15505
15506#ifdef HAVE_FUTIMENS
15507 { "HAVE_FUTIMENS", probe_futimens },
15508#endif
15509
15510#ifdef HAVE_FUTIMES
15511 { "HAVE_FUTIMES", NULL },
15512#endif
15513
15514#ifdef HAVE_FUTIMESAT
15515 { "HAVE_FUTIMESAT", NULL },
15516#endif
15517
15518#ifdef HAVE_LINKAT
15519 { "HAVE_LINKAT", probe_linkat },
15520#endif
15521
15522#ifdef HAVE_LCHFLAGS
15523 { "HAVE_LCHFLAGS", NULL },
15524#endif
15525
15526#ifdef HAVE_LCHMOD
15527 { "HAVE_LCHMOD", NULL },
15528#endif
15529
15530#ifdef HAVE_LCHOWN
15531 { "HAVE_LCHOWN", NULL },
15532#endif
15533
15534#ifdef HAVE_LSTAT
15535 { "HAVE_LSTAT", NULL },
15536#endif
15537
15538#ifdef HAVE_LUTIMES
15539 { "HAVE_LUTIMES", NULL },
15540#endif
15541
15542#ifdef HAVE_MEMFD_CREATE
15543 { "HAVE_MEMFD_CREATE", NULL },
15544#endif
15545
15546#ifdef HAVE_MKDIRAT
15547 { "HAVE_MKDIRAT", probe_mkdirat },
15548#endif
15549
15550#ifdef HAVE_MKFIFOAT
15551 { "HAVE_MKFIFOAT", NULL },
15552#endif
15553
15554#ifdef HAVE_MKNODAT
15555 { "HAVE_MKNODAT", NULL },
15556#endif
15557
15558#ifdef HAVE_OPENAT
15559 { "HAVE_OPENAT", probe_openat },
15560#endif
15561
15562#ifdef HAVE_READLINKAT
15563 { "HAVE_READLINKAT", probe_readlinkat },
15564#endif
15565
15566#ifdef HAVE_RENAMEAT
15567 { "HAVE_RENAMEAT", probe_renameat },
15568#endif
15569
15570#ifdef HAVE_SYMLINKAT
15571 { "HAVE_SYMLINKAT", probe_symlinkat },
15572#endif
15573
15574#ifdef HAVE_UNLINKAT
15575 { "HAVE_UNLINKAT", probe_unlinkat },
15576#endif
15577
15578#ifdef HAVE_UTIMENSAT
15579 { "HAVE_UTIMENSAT", probe_utimensat },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015580#endif
15581
15582#ifdef MS_WINDOWS
Ronald Oussoren41761932020-11-08 10:05:27 +010015583 { "MS_WINDOWS", NULL },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015584#endif
15585
Ronald Oussoren41761932020-11-08 10:05:27 +010015586 { NULL, NULL }
Larry Hastings9cf065c2012-06-22 16:30:09 -070015587};
15588
15589
Victor Stinner1c2fa782020-05-10 11:05:29 +020015590static int
15591posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000015592{
Victor Stinner97f33c32020-05-14 18:05:58 +020015593 _posixstate *state = get_posix_state(m);
Tim Peters5aa91602002-01-30 05:46:57 +000015594
Ronald Oussoren41761932020-11-08 10:05:27 +010015595#if defined(HAVE_PWRITEV)
15596 if (HAVE_PWRITEV_RUNTIME) {} else {
15597 PyObject* dct = PyModule_GetDict(m);
15598
15599 if (dct == NULL) {
15600 return -1;
15601 }
15602
15603 if (PyDict_DelItemString(dct, "pwritev") == -1) {
15604 PyErr_Clear();
15605 }
15606 if (PyDict_DelItemString(dct, "preadv") == -1) {
15607 PyErr_Clear();
15608 }
15609 }
15610#endif
15611
Victor Stinner8c62be82010-05-06 00:08:46 +000015612 /* Initialize environ dictionary */
Victor Stinner97f33c32020-05-14 18:05:58 +020015613 PyObject *v = convertenviron();
Victor Stinner8c62be82010-05-06 00:08:46 +000015614 Py_XINCREF(v);
15615 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015616 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015617 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000015618
Victor Stinner8c62be82010-05-06 00:08:46 +000015619 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015620 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000015621
Victor Stinner8c62be82010-05-06 00:08:46 +000015622 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015623 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000015624
Victor Stinner8c62be82010-05-06 00:08:46 +000015625 Py_INCREF(PyExc_OSError);
15626 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000015627
Ross Lagerwall7807c352011-03-17 20:20:30 +020015628#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080015629 waitid_result_desc.name = MODNAME ".waitid_result";
15630 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
15631 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015632 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015633 }
15634 Py_INCREF(WaitidResultType);
15635 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015636 state->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015637#endif
15638
Eddie Elizondob3966632019-11-05 07:16:14 -080015639 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
15640 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
15641 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
15642 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
15643 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
15644 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015645 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015646 }
15647 Py_INCREF(StatResultType);
15648 PyModule_AddObject(m, "stat_result", StatResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015649 state->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015650 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
15651 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015652
Eddie Elizondob3966632019-11-05 07:16:14 -080015653 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
15654 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
15655 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015656 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015657 }
15658 Py_INCREF(StatVFSResultType);
15659 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015660 state->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015661#ifdef NEED_TICKS_PER_SECOND
15662# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080015663 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015664# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080015665 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015666# else
Eddie Elizondob3966632019-11-05 07:16:14 -080015667 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015668# endif
15669#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015670
William Orr81574b82018-10-01 22:19:56 -070015671#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080015672 sched_param_desc.name = MODNAME ".sched_param";
15673 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
15674 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015675 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015676 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015677 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080015678 PyModule_AddObject(m, "sched_param", SchedParamType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015679 state->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015680 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050015681#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000015682
Eddie Elizondob3966632019-11-05 07:16:14 -080015683 /* initialize TerminalSize_info */
15684 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
15685 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015686 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015687 }
15688 Py_INCREF(TerminalSizeType);
15689 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015690 state->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015691
15692 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020015693 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015694 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015695 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015696 }
Victor Stinner97f33c32020-05-14 18:05:58 +020015697 state->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015698
Victor Stinner1c2fa782020-05-10 11:05:29 +020015699 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015700 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015701 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015702 }
15703 Py_INCREF(DirEntryType);
15704 PyModule_AddObject(m, "DirEntry", DirEntryType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015705 state->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015706
Larry Hastings605a62d2012-06-24 04:33:36 -070015707 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080015708 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015709 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015710 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015711 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015712 Py_INCREF(TimesResultType);
15713 PyModule_AddObject(m, "times_result", TimesResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015714 state->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015715
Eddie Elizondob3966632019-11-05 07:16:14 -080015716 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015717 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015718 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015719 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015720 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015721 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015722 state->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015723
Victor Stinner97f33c32020-05-14 18:05:58 +020015724 if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015725 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015726#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +020015727 state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
15728 if (state->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015729 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015730#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020015731 state->st_mode = PyUnicode_InternFromString("st_mode");
15732 if (state->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015733 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070015734
Larry Hastings9cf065c2012-06-22 16:30:09 -070015735 /* suppress "function not used" warnings */
15736 {
15737 int ignored;
15738 fd_specified("", -1);
15739 follow_symlinks_specified("", 1);
15740 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
15741 dir_fd_converter(Py_None, &ignored);
15742 dir_fd_unavailable(Py_None, &ignored);
15743 }
15744
15745 /*
15746 * provide list of locally available functions
15747 * so os.py can populate support_* lists
15748 */
Victor Stinner97f33c32020-05-14 18:05:58 +020015749 PyObject *list = PyList_New(0);
15750 if (!list) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015751 return -1;
Victor Stinner97f33c32020-05-14 18:05:58 +020015752 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015753 for (const struct have_function *trace = have_functions; trace->label; trace++) {
15754 PyObject *unicode;
15755 if (trace->probe && !trace->probe()) continue;
15756 unicode = PyUnicode_DecodeASCII(trace->label, strlen(trace->label), NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015757 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015758 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015759 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015760 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015761 Py_DECREF(unicode);
15762 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015763
Larry Hastings9cf065c2012-06-22 16:30:09 -070015764 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040015765
Victor Stinner1c2fa782020-05-10 11:05:29 +020015766 return 0;
15767}
15768
15769
15770static PyModuleDef_Slot posixmodile_slots[] = {
15771 {Py_mod_exec, posixmodule_exec},
15772 {0, NULL}
15773};
15774
15775static struct PyModuleDef posixmodule = {
15776 PyModuleDef_HEAD_INIT,
15777 .m_name = MODNAME,
15778 .m_doc = posix__doc__,
15779 .m_size = sizeof(_posixstate),
15780 .m_methods = posix_methods,
15781 .m_slots = posixmodile_slots,
15782 .m_traverse = _posix_traverse,
15783 .m_clear = _posix_clear,
15784 .m_free = _posix_free,
15785};
15786
15787PyMODINIT_FUNC
15788INITFUNC(void)
15789{
15790 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015791}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015792
15793#ifdef __cplusplus
15794}
15795#endif