blob: b30ae80290535ac35c2766739872bb1899643e2a [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* POSIX module implementation */
2
Jesus Ceaab70e2a2012-10-05 01:48:08 +02003/* This file is also used for Windows NT/MS-Win. In that case the
4 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00007 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02008 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +00009
Thomas Wouters68bc4f92006-03-01 01:05:10 +000010#define PY_SSIZE_T_CLEAN
11
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000012#include "Python.h"
Kyle Evans79925792020-10-13 15:04:44 -050013#include "pycore_fileutils.h"
Victor Stinnerd5d9e812019-05-13 12:35:37 +020014#ifdef MS_WINDOWS
15 /* include <windows.h> early to avoid conflict with pycore_condvar.h:
16
17 #define WIN32_LEAN_AND_MEAN
18 #include <windows.h>
19
20 FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
21# include <windows.h>
22#endif
23
pxinwr3405e052020-08-07 13:21:52 +080024#ifdef __VXWORKS__
25# include "pycore_bitutils.h" // _Py_popcount32()
26#endif
Victor Stinner4a21e572020-04-15 02:35:41 +020027#include "pycore_ceval.h" // _PyEval_ReInitThreads()
28#include "pycore_import.h" // _PyImport_ReInitLock()
Victor Stinner26881c82020-06-02 15:51:37 +020029#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
Victor Stinner4a21e572020-04-15 02:35:41 +020030#include "pycore_pystate.h" // _PyInterpreterState_GET()
31#include "structmember.h" // PyMemberDef
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020032#ifndef MS_WINDOWS
Victor Stinnerd5d9e812019-05-13 12:35:37 +020033# include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010034#else
Victor Stinnerd5d9e812019-05-13 12:35:37 +020035# include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020036#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000037
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020038/* On android API level 21, 'AT_EACCESS' is not declared although
39 * HAVE_FACCESSAT is defined. */
40#ifdef __ANDROID__
Victor Stinner5eca75d2020-04-15 15:07:31 +020041# undef HAVE_FACCESSAT
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020042#endif
43
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000044#include <stdio.h> /* needed for ctermid() */
45
Ronald Oussoren41761932020-11-08 10:05:27 +010046/*
47 * A number of APIs are available on macOS from a certain macOS version.
48 * To support building with a new SDK while deploying to older versions
49 * the availability test is split into two:
50 * - HAVE_<FUNCTION>: The configure check for compile time availability
51 * - HAVE_<FUNCTION>_RUNTIME: Runtime check for availability
52 *
53 * The latter is always true when not on macOS, or when using a compiler
54 * that does not support __has_builtin (older versions of Xcode).
55 *
56 * Due to compiler restrictions there is one valid use of HAVE_<FUNCTION>_RUNTIME:
57 * if (HAVE_<FUNCTION>_RUNTIME) { ... }
58 *
59 * In mixing the test with other tests or using negations will result in compile
60 * errors.
61 */
62#if defined(__APPLE__)
63
Joshua Rootdf21f502021-01-04 21:36:58 +110064#if defined(__has_builtin)
65#if __has_builtin(__builtin_available)
66#define HAVE_BUILTIN_AVAILABLE 1
67#endif
68#endif
69
70#ifdef HAVE_BUILTIN_AVAILABLE
Ronald Oussoren41761932020-11-08 10:05:27 +010071# define HAVE_FSTATAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
72# define HAVE_FACCESSAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
73# define HAVE_FCHMODAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
74# define HAVE_FCHOWNAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
75# define HAVE_LINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
76# define HAVE_FDOPENDIR_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
77# define HAVE_MKDIRAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
78# define HAVE_RENAMEAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
79# define HAVE_UNLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
80# define HAVE_OPENAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
81# define HAVE_READLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
82# define HAVE_SYMLINKAT_RUNTIME __builtin_available(macOS 10.10, iOS 8.0, *)
83# define HAVE_FUTIMENS_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
84# define HAVE_UTIMENSAT_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)
85# define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
86
87# define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *)
88
89#else /* Xcode 8 or earlier */
90
91 /* __builtin_available is not present in these compilers, but
92 * some of the symbols might be weak linked (10.10 SDK or later
93 * deploying on 10.9.
94 *
95 * Fall back to the older style of availability checking for
96 * symbols introduced in macOS 10.10.
97 */
98
99# ifdef HAVE_FSTATAT
100# define HAVE_FSTATAT_RUNTIME (fstatat != NULL)
101# endif
102
103# ifdef HAVE_FACCESSAT
104# define HAVE_FACCESSAT_RUNTIME (faccessat != NULL)
105# endif
106
107# ifdef HAVE_FCHMODAT
108# define HAVE_FCHMODAT_RUNTIME (fchmodat != NULL)
109# endif
110
111# ifdef HAVE_FCHOWNAT
112# define HAVE_FCHOWNAT_RUNTIME (fchownat != NULL)
113# endif
114
115# ifdef HAVE_LINKAT
116# define HAVE_LINKAT_RUNTIME (linkat != NULL)
117# endif
118
119# ifdef HAVE_FDOPENDIR
120# define HAVE_FDOPENDIR_RUNTIME (fdopendir != NULL)
121# endif
122
123# ifdef HAVE_MKDIRAT
124# define HAVE_MKDIRAT_RUNTIME (mkdirat != NULL)
125# endif
126
127# ifdef HAVE_RENAMEAT
128# define HAVE_RENAMEAT_RUNTIME (renameat != NULL)
129# endif
130
131# ifdef HAVE_UNLINKAT
132# define HAVE_UNLINKAT_RUNTIME (unlinkat != NULL)
133# endif
134
135# ifdef HAVE_OPENAT
136# define HAVE_OPENAT_RUNTIME (openat != NULL)
137# endif
138
139# ifdef HAVE_READLINKAT
140# define HAVE_READLINKAT_RUNTIME (readlinkat != NULL)
141# endif
142
143# ifdef HAVE_SYMLINKAT
144# define HAVE_SYMLINKAT_RUNTIME (symlinkat != NULL)
145# endif
146
147#endif
148
149#ifdef HAVE_FUTIMESAT
150/* Some of the logic for weak linking depends on this assertion */
151# error "HAVE_FUTIMESAT unexpectedly defined"
152#endif
153
154#else
155# define HAVE_FSTATAT_RUNTIME 1
156# define HAVE_FACCESSAT_RUNTIME 1
157# define HAVE_FCHMODAT_RUNTIME 1
158# define HAVE_FCHOWNAT_RUNTIME 1
159# define HAVE_LINKAT_RUNTIME 1
160# define HAVE_FDOPENDIR_RUNTIME 1
161# define HAVE_MKDIRAT_RUNTIME 1
162# define HAVE_RENAMEAT_RUNTIME 1
163# define HAVE_UNLINKAT_RUNTIME 1
164# define HAVE_OPENAT_RUNTIME 1
165# define HAVE_READLINKAT_RUNTIME 1
166# define HAVE_SYMLINKAT_RUNTIME 1
167# define HAVE_FUTIMENS_RUNTIME 1
168# define HAVE_UTIMENSAT_RUNTIME 1
169# define HAVE_PWRITEV_RUNTIME 1
170#endif
171
172
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000173#ifdef __cplusplus
174extern "C" {
175#endif
176
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000177PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000178"This module provides access to operating system functionality that is\n\
179standardized by the C Standard and the POSIX standard (a thinly\n\
180disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000181corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182
Martin v. Löwis0073f2e2002-11-21 23:52:35 +0000183
Ross Lagerwall4d076da2011-03-18 06:56:53 +0200184#ifdef HAVE_SYS_UIO_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200185# include <sys/uio.h>
Ross Lagerwall4d076da2011-03-18 06:56:53 +0200186#endif
187
Christian Heimes75b96182017-09-05 15:53:09 +0200188#ifdef HAVE_SYS_SYSMACROS_H
189/* GNU C Library: major(), minor(), makedev() */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200190# include <sys/sysmacros.h>
Christian Heimes75b96182017-09-05 15:53:09 +0200191#endif
192
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000193#ifdef HAVE_SYS_TYPES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200194# include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000195#endif /* HAVE_SYS_TYPES_H */
196
197#ifdef HAVE_SYS_STAT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200198# include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000199#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000200
Guido van Rossum36bc6801995-06-14 22:54:23 +0000201#ifdef HAVE_SYS_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200202# include <sys/wait.h> // WNOHANG
Guido van Rossum36bc6801995-06-14 22:54:23 +0000203#endif
Benjamin Peterson5c0c3252019-11-05 21:58:31 -0800204#ifdef HAVE_LINUX_WAIT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200205# include <linux/wait.h> // P_PIDFD
Benjamin Peterson5c0c3252019-11-05 21:58:31 -0800206#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000208#ifdef HAVE_SIGNAL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200209# include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000210#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +0000211
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_FCNTL_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200213# include <fcntl.h>
214#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000216#ifdef HAVE_GRP_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200217# include <grp.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +0000218#endif
219
Barry Warsaw5676bd12003-01-07 20:57:09 +0000220#ifdef HAVE_SYSEXITS_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200221# include <sysexits.h>
222#endif
Barry Warsaw5676bd12003-01-07 20:57:09 +0000223
Anthony Baxter8a560de2004-10-13 15:30:56 +0000224#ifdef HAVE_SYS_LOADAVG_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200225# include <sys/loadavg.h>
Anthony Baxter8a560de2004-10-13 15:30:56 +0000226#endif
227
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000228#ifdef HAVE_SYS_SENDFILE_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200229# include <sys/sendfile.h>
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000230#endif
231
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200232#if defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200233# include <copyfile.h>
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +0200234#endif
235
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500236#ifdef HAVE_SCHED_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200237# include <sched.h>
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500238#endif
239
Pablo Galindoaac4d032019-05-31 19:39:47 +0100240#ifdef HAVE_COPY_FILE_RANGE
Victor Stinner5eca75d2020-04-15 15:07:31 +0200241# include <unistd.h>
Pablo Galindoaac4d032019-05-31 19:39:47 +0100242#endif
243
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500244#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200245# undef HAVE_SCHED_SETAFFINITY
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500246#endif
247
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200248#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200249# define USE_XATTRS
Benjamin Peterson9428d532011-09-14 11:45:52 -0400250#endif
251
252#ifdef USE_XATTRS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200253# include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400254#endif
255
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000256#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200257# ifdef HAVE_SYS_SOCKET_H
258# include <sys/socket.h>
259# endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000260#endif
261
Victor Stinner8b905bd2011-10-25 13:34:04 +0200262#ifdef HAVE_DLFCN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200263# include <dlfcn.h>
Victor Stinner8b905bd2011-10-25 13:34:04 +0200264#endif
265
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200266#ifdef __hpux
Victor Stinner5eca75d2020-04-15 15:07:31 +0200267# include <sys/mpctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200268#endif
269
270#if defined(__DragonFly__) || \
271 defined(__OpenBSD__) || \
272 defined(__FreeBSD__) || \
273 defined(__NetBSD__) || \
274 defined(__APPLE__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200275# include <sys/sysctl.h>
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200276#endif
277
Victor Stinner9b1f4742016-09-06 16:18:52 -0700278#ifdef HAVE_LINUX_RANDOM_H
279# include <linux/random.h>
280#endif
281#ifdef HAVE_GETRANDOM_SYSCALL
282# include <sys/syscall.h>
283#endif
284
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100285#if defined(MS_WINDOWS)
286# define TERMSIZE_USE_CONIO
287#elif defined(HAVE_SYS_IOCTL_H)
288# include <sys/ioctl.h>
289# if defined(HAVE_TERMIOS_H)
290# include <termios.h>
291# endif
292# if defined(TIOCGWINSZ)
293# define TERMSIZE_USE_IOCTL
294# endif
295#endif /* MS_WINDOWS */
296
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000297/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000298/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000299#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200300# define HAVE_OPENDIR 1
301# define HAVE_SYSTEM 1
302# include <process.h>
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000303#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200304# ifdef _MSC_VER
305 /* Microsoft compiler */
306# define HAVE_GETPPID 1
307# define HAVE_GETLOGIN 1
308# define HAVE_SPAWNV 1
309# define HAVE_EXECV 1
310# define HAVE_WSPAWNV 1
311# define HAVE_WEXECV 1
312# define HAVE_PIPE 1
313# define HAVE_SYSTEM 1
314# define HAVE_CWAIT 1
315# define HAVE_FSYNC 1
316# define fsync _commit
317# else
318 /* Unix functions that the configure script doesn't check for */
319# ifndef __VXWORKS__
320# define HAVE_EXECV 1
321# define HAVE_FORK 1
322# if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
323# define HAVE_FORK1 1
324# endif
325# endif
326# define HAVE_GETEGID 1
327# define HAVE_GETEUID 1
328# define HAVE_GETGID 1
329# define HAVE_GETPPID 1
330# define HAVE_GETUID 1
331# define HAVE_KILL 1
332# define HAVE_OPENDIR 1
333# define HAVE_PIPE 1
334# define HAVE_SYSTEM 1
335# define HAVE_WAIT 1
336# define HAVE_TTYNAME 1
337# endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000338#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000339
Eddie Elizondob3966632019-11-05 07:16:14 -0800340_Py_IDENTIFIER(__fspath__);
Victor Stinnera2f7c002012-02-08 03:36:25 +0100341
Larry Hastings61272b72014-01-07 12:41:53 -0800342/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000343# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800344module os
Larry Hastings61272b72014-01-07 12:41:53 -0800345[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000346/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100347
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000348#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000349
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000350#if defined(__sgi)&&_COMPILER_VERSION>=700
351/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
352 (default) */
353extern char *ctermid_r(char *);
354#endif
355
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000356#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357
pxinwrf2d7ac72019-05-21 18:46:37 +0800358#if defined(__VXWORKS__)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200359# include <vxCpuLib.h>
360# include <rtpLib.h>
361# include <wait.h>
362# include <taskLib.h>
363# ifndef _P_WAIT
364# define _P_WAIT 0
365# define _P_NOWAIT 1
366# define _P_NOWAITO 1
367# endif
pxinwrf2d7ac72019-05-21 18:46:37 +0800368#endif /* __VXWORKS__ */
369
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000370#ifdef HAVE_POSIX_SPAWN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200371# include <spawn.h>
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000372#endif
373
Guido van Rossumb6775db1994-08-01 11:34:53 +0000374#ifdef HAVE_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200375# include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000376#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000377
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000378#ifdef HAVE_SYS_UTIME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200379# include <sys/utime.h>
380# define HAVE_UTIME_H /* pretend we do for the rest of this file */
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000381#endif /* HAVE_SYS_UTIME_H */
382
Guido van Rossumb6775db1994-08-01 11:34:53 +0000383#ifdef HAVE_SYS_TIMES_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200384# include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000385#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000386
387#ifdef HAVE_SYS_PARAM_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200388# include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000389#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000390
391#ifdef HAVE_SYS_UTSNAME_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200392# include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000393#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000394
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000395#ifdef HAVE_DIRENT_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200396# include <dirent.h>
397# define NAMLEN(dirent) strlen((dirent)->d_name)
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000398#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200399# if defined(__WATCOMC__) && !defined(__QNX__)
400# include <direct.h>
401# define NAMLEN(dirent) strlen((dirent)->d_name)
402# else
403# define dirent direct
404# define NAMLEN(dirent) (dirent)->d_namlen
405# endif
406# ifdef HAVE_SYS_NDIR_H
407# include <sys/ndir.h>
408# endif
409# ifdef HAVE_SYS_DIR_H
410# include <sys/dir.h>
411# endif
412# ifdef HAVE_NDIR_H
413# include <ndir.h>
414# endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000415#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000416
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000417#ifdef _MSC_VER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200418# ifdef HAVE_DIRECT_H
419# include <direct.h>
420# endif
421# ifdef HAVE_IO_H
422# include <io.h>
423# endif
424# ifdef HAVE_PROCESS_H
425# include <process.h>
426# endif
427# ifndef IO_REPARSE_TAG_SYMLINK
428# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
429# endif
430# ifndef IO_REPARSE_TAG_MOUNT_POINT
431# define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
432# endif
433# include "osdefs.h" // SEP
434# include <malloc.h>
435# include <windows.h>
436# include <shellapi.h> // ShellExecute()
437# include <lmcons.h> // UNLEN
438# define HAVE_SYMLINK
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000439#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000440
Tim Petersbc2e10e2002-03-03 23:17:02 +0000441#ifndef MAXPATHLEN
Victor Stinner5eca75d2020-04-15 15:07:31 +0200442# if defined(PATH_MAX) && PATH_MAX > 1024
443# define MAXPATHLEN PATH_MAX
444# else
445# define MAXPATHLEN 1024
446# endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000447#endif /* MAXPATHLEN */
448
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000449#ifdef UNION_WAIT
Victor Stinner5eca75d2020-04-15 15:07:31 +0200450 /* Emulate some macros on systems that have a union instead of macros */
451# ifndef WIFEXITED
452# define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
453# endif
454# ifndef WEXITSTATUS
455# define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
456# endif
457# ifndef WTERMSIG
458# define WTERMSIG(u_wait) ((u_wait).w_termsig)
459# endif
460# define WAIT_TYPE union wait
461# define WAIT_STATUS_INT(s) (s.w_status)
462#else
463 /* !UNION_WAIT */
464# define WAIT_TYPE int
465# define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000466#endif /* UNION_WAIT */
467
Greg Wardb48bc172000-03-01 21:51:56 +0000468/* Don't use the "_r" form if we don't need it (also, won't have a
469 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200470#if defined(HAVE_CTERMID_R)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200471# define USE_CTERMID_R
Greg Wardb48bc172000-03-01 21:51:56 +0000472#endif
473
Fred Drake699f3522000-06-29 21:12:41 +0000474/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000475#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000476#undef FSTAT
477#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200478#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200479# define STAT win32_stat
480# define LSTAT win32_lstat
481# define FSTAT _Py_fstat_noraise
482# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000483#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200484# define STAT stat
485# define LSTAT lstat
486# define FSTAT fstat
487# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000488#endif
489
Tim Peters11b23062003-04-23 02:39:17 +0000490#if defined(MAJOR_IN_MKDEV)
Victor Stinner5eca75d2020-04-15 15:07:31 +0200491# include <sys/mkdev.h>
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000492#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200493# if defined(MAJOR_IN_SYSMACROS)
494# include <sys/sysmacros.h>
495# endif
496# if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
497# include <sys/mkdev.h>
498# endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000499#endif
Fred Drake699f3522000-06-29 21:12:41 +0000500
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200501#ifdef MS_WINDOWS
Victor Stinner5eca75d2020-04-15 15:07:31 +0200502# define INITFUNC PyInit_nt
503# define MODNAME "nt"
Victor Stinner6036e442015-03-08 01:58:04 +0100504#else
Victor Stinner5eca75d2020-04-15 15:07:31 +0200505# define INITFUNC PyInit_posix
506# define MODNAME "posix"
Victor Stinner6036e442015-03-08 01:58:04 +0100507#endif
508
jcea6c51d512018-01-28 14:00:08 +0100509#if defined(__sun)
510/* Something to implement in autoconf, not present in autoconf 2.69 */
Victor Stinner5eca75d2020-04-15 15:07:31 +0200511# define HAVE_STRUCT_STAT_ST_FSTYPE 1
jcea6c51d512018-01-28 14:00:08 +0100512#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200513
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600514/* memfd_create is either defined in sys/mman.h or sys/memfd.h
515 * linux/memfd.h defines additional flags
516 */
517#ifdef HAVE_SYS_MMAN_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200518# include <sys/mman.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600519#endif
520#ifdef HAVE_SYS_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200521# include <sys/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600522#endif
523#ifdef HAVE_LINUX_MEMFD_H
Victor Stinner5eca75d2020-04-15 15:07:31 +0200524# include <linux/memfd.h>
Zackery Spytz43fdbd22019-05-29 13:57:07 -0600525#endif
526
Christian Heimescd9fed62020-11-13 19:48:52 +0100527/* eventfd() */
528#ifdef HAVE_SYS_EVENTFD_H
529# include <sys/eventfd.h>
530#endif
531
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800532#ifdef _Py_MEMORY_SANITIZER
Victor Stinner5eca75d2020-04-15 15:07:31 +0200533# include <sanitizer/msan_interface.h>
Gregory P. Smith1d300ce2018-12-30 21:13:02 -0800534#endif
535
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200536#ifdef HAVE_FORK
537static void
538run_at_forkers(PyObject *lst, int reverse)
539{
540 Py_ssize_t i;
541 PyObject *cpy;
542
543 if (lst != NULL) {
544 assert(PyList_CheckExact(lst));
545
546 /* Use a list copy in case register_at_fork() is called from
547 * one of the callbacks.
548 */
549 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
550 if (cpy == NULL)
551 PyErr_WriteUnraisable(lst);
552 else {
553 if (reverse)
554 PyList_Reverse(cpy);
555 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
556 PyObject *func, *res;
557 func = PyList_GET_ITEM(cpy, i);
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +0200558 res = _PyObject_CallNoArg(func);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200559 if (res == NULL)
560 PyErr_WriteUnraisable(func);
561 else
562 Py_DECREF(res);
563 }
564 Py_DECREF(cpy);
565 }
566 }
567}
568
569void
570PyOS_BeforeFork(void)
571{
Victor Stinner81a7be32020-04-14 15:14:01 +0200572 run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200573
574 _PyImport_AcquireLock();
575}
576
577void
578PyOS_AfterFork_Parent(void)
579{
580 if (_PyImport_ReleaseLock() <= 0)
581 Py_FatalError("failed releasing import lock after fork");
582
Victor Stinner81a7be32020-04-14 15:14:01 +0200583 run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200584}
585
586void
587PyOS_AfterFork_Child(void)
588{
Victor Stinner26881c82020-06-02 15:51:37 +0200589 PyStatus status;
Victor Stinnerb930a2d2019-04-24 17:14:33 +0200590 _PyRuntimeState *runtime = &_PyRuntime;
Victor Stinner26881c82020-06-02 15:51:37 +0200591
592 status = _PyGILState_Reinit(runtime);
593 if (_PyStatus_EXCEPTION(status)) {
594 goto fatal_error;
595 }
596
Victor Stinner317bab02020-06-02 18:44:54 +0200597 PyThreadState *tstate = _PyThreadState_GET();
598 _Py_EnsureTstateNotNULL(tstate);
599
600 status = _PyEval_ReInitThreads(tstate);
Victor Stinner26881c82020-06-02 15:51:37 +0200601 if (_PyStatus_EXCEPTION(status)) {
602 goto fatal_error;
603 }
604
605 status = _PyImport_ReInitLock();
606 if (_PyStatus_EXCEPTION(status)) {
607 goto fatal_error;
608 }
609
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200610 _PySignal_AfterFork();
Victor Stinner26881c82020-06-02 15:51:37 +0200611
612 status = _PyRuntimeState_ReInitThreads(runtime);
613 if (_PyStatus_EXCEPTION(status)) {
614 goto fatal_error;
615 }
616
617 status = _PyInterpreterState_DeleteExceptMain(runtime);
618 if (_PyStatus_EXCEPTION(status)) {
619 goto fatal_error;
620 }
Victor Stinner317bab02020-06-02 18:44:54 +0200621 assert(_PyThreadState_GET() == tstate);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200622
Victor Stinner317bab02020-06-02 18:44:54 +0200623 run_at_forkers(tstate->interp->after_forkers_child, 0);
Victor Stinner26881c82020-06-02 15:51:37 +0200624 return;
625
626fatal_error:
627 Py_ExitStatusException(status);
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200628}
629
630static int
631register_at_forker(PyObject **lst, PyObject *func)
632{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700633 if (func == NULL) /* nothing to register? do nothing. */
634 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200635 if (*lst == NULL) {
636 *lst = PyList_New(0);
637 if (*lst == NULL)
638 return -1;
639 }
640 return PyList_Append(*lst, func);
641}
Victor Stinner87255be2020-04-07 23:11:49 +0200642#endif /* HAVE_FORK */
643
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200644
645/* Legacy wrapper */
646void
647PyOS_AfterFork(void)
648{
649#ifdef HAVE_FORK
650 PyOS_AfterFork_Child();
651#endif
652}
653
654
Victor Stinner6036e442015-03-08 01:58:04 +0100655#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200656/* defined in fileutils.c */
Benjamin Petersone5024512018-09-12 12:06:42 -0700657void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
658void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200659 ULONG, struct _Py_stat_struct *);
660#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700661
Larry Hastings9cf065c2012-06-22 16:30:09 -0700662
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200663#ifndef MS_WINDOWS
664PyObject *
665_PyLong_FromUid(uid_t uid)
666{
667 if (uid == (uid_t)-1)
668 return PyLong_FromLong(-1);
669 return PyLong_FromUnsignedLong(uid);
670}
671
672PyObject *
673_PyLong_FromGid(gid_t gid)
674{
675 if (gid == (gid_t)-1)
676 return PyLong_FromLong(-1);
677 return PyLong_FromUnsignedLong(gid);
678}
679
680int
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100681_Py_Uid_Converter(PyObject *obj, uid_t *p)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200682{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700683 uid_t uid;
684 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200685 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200686 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700687 unsigned long uresult;
688
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300689 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700690 if (index == NULL) {
691 PyErr_Format(PyExc_TypeError,
692 "uid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800693 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200694 return 0;
695 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700696
697 /*
698 * Handling uid_t is complicated for two reasons:
699 * * Although uid_t is (always?) unsigned, it still
700 * accepts -1.
701 * * We don't know its size in advance--it may be
702 * bigger than an int, or it may be smaller than
703 * a long.
704 *
705 * So a bit of defensive programming is in order.
706 * Start with interpreting the value passed
707 * in as a signed long and see if it works.
708 */
709
710 result = PyLong_AsLongAndOverflow(index, &overflow);
711
712 if (!overflow) {
713 uid = (uid_t)result;
714
715 if (result == -1) {
716 if (PyErr_Occurred())
717 goto fail;
718 /* It's a legitimate -1, we're done. */
719 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200720 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700721
722 /* Any other negative number is disallowed. */
723 if (result < 0)
724 goto underflow;
725
726 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200727 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700728 (long)uid != result)
729 goto underflow;
730 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200731 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700732
733 if (overflow < 0)
734 goto underflow;
735
736 /*
737 * Okay, the value overflowed a signed long. If it
738 * fits in an *unsigned* long, it may still be okay,
739 * as uid_t may be unsigned long on this platform.
740 */
741 uresult = PyLong_AsUnsignedLong(index);
742 if (PyErr_Occurred()) {
743 if (PyErr_ExceptionMatches(PyExc_OverflowError))
744 goto overflow;
745 goto fail;
746 }
747
748 uid = (uid_t)uresult;
749
750 /*
751 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
752 * but this value would get interpreted as (uid_t)-1 by chown
753 * and its siblings. That's not what the user meant! So we
754 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100755 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700756 */
757 if (uid == (uid_t)-1)
758 goto overflow;
759
760 /* Ensure the value wasn't truncated. */
761 if (sizeof(uid_t) < sizeof(long) &&
762 (unsigned long)uid != uresult)
763 goto overflow;
764 /* fallthrough */
765
766success:
767 Py_DECREF(index);
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100768 *p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200769 return 1;
770
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700771underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200772 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700773 "uid is less than minimum");
774 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200775
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700776overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200777 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700778 "uid is greater than maximum");
779 /* fallthrough */
780
781fail:
782 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200783 return 0;
784}
785
786int
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100787_Py_Gid_Converter(PyObject *obj, gid_t *p)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200788{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700789 gid_t gid;
790 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200791 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200792 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700793 unsigned long uresult;
794
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300795 index = _PyNumber_Index(obj);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700796 if (index == NULL) {
797 PyErr_Format(PyExc_TypeError,
798 "gid should be integer, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800799 _PyType_Name(Py_TYPE(obj)));
Serhiy Storchakab4621892013-02-10 23:28:02 +0200800 return 0;
801 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700802
803 /*
804 * Handling gid_t is complicated for two reasons:
805 * * Although gid_t is (always?) unsigned, it still
806 * accepts -1.
807 * * We don't know its size in advance--it may be
808 * bigger than an int, or it may be smaller than
809 * a long.
810 *
811 * So a bit of defensive programming is in order.
812 * Start with interpreting the value passed
813 * in as a signed long and see if it works.
814 */
815
816 result = PyLong_AsLongAndOverflow(index, &overflow);
817
818 if (!overflow) {
819 gid = (gid_t)result;
820
821 if (result == -1) {
822 if (PyErr_Occurred())
823 goto fail;
824 /* It's a legitimate -1, we're done. */
825 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200826 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700827
828 /* Any other negative number is disallowed. */
829 if (result < 0) {
830 goto underflow;
831 }
832
833 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200834 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700835 (long)gid != result)
836 goto underflow;
837 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200838 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700839
840 if (overflow < 0)
841 goto underflow;
842
843 /*
844 * Okay, the value overflowed a signed long. If it
845 * fits in an *unsigned* long, it may still be okay,
846 * as gid_t may be unsigned long on this platform.
847 */
848 uresult = PyLong_AsUnsignedLong(index);
849 if (PyErr_Occurred()) {
850 if (PyErr_ExceptionMatches(PyExc_OverflowError))
851 goto overflow;
852 goto fail;
853 }
854
855 gid = (gid_t)uresult;
856
857 /*
858 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
859 * but this value would get interpreted as (gid_t)-1 by chown
860 * and its siblings. That's not what the user meant! So we
861 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100862 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700863 */
864 if (gid == (gid_t)-1)
865 goto overflow;
866
867 /* Ensure the value wasn't truncated. */
868 if (sizeof(gid_t) < sizeof(long) &&
869 (unsigned long)gid != uresult)
870 goto overflow;
871 /* fallthrough */
872
873success:
874 Py_DECREF(index);
Jakub Kulík0159e5e2020-12-29 13:58:27 +0100875 *p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200876 return 1;
877
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700878underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200879 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700880 "gid is less than minimum");
881 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200882
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700883overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200884 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700885 "gid is greater than maximum");
886 /* fallthrough */
887
888fail:
889 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200890 return 0;
891}
892#endif /* MS_WINDOWS */
893
894
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700895#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800896
897
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200898#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
899static int
900_Py_Dev_Converter(PyObject *obj, void *p)
901{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200902 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200903 if (PyErr_Occurred())
904 return 0;
905 return 1;
906}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800907#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200908
909
Larry Hastings9cf065c2012-06-22 16:30:09 -0700910#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400911/*
912 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
913 * without the int cast, the value gets interpreted as uint (4291925331),
914 * which doesn't play nicely with all the initializer lines in this file that
915 * look like this:
916 * int dir_fd = DEFAULT_DIR_FD;
917 */
918#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700919#else
920#define DEFAULT_DIR_FD (-100)
921#endif
922
923static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300924_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200925{
926 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700927 long long_value;
928
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300929 PyObject *index = _PyNumber_Index(o);
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700930 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700931 return 0;
932 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700933
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300934 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700935 long_value = PyLong_AsLongAndOverflow(index, &overflow);
936 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300937 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200938 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700939 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700940 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941 return 0;
942 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200943 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700944 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700945 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700946 return 0;
947 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700948
Larry Hastings9cf065c2012-06-22 16:30:09 -0700949 *p = (int)long_value;
950 return 1;
951}
952
953static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200954dir_fd_converter(PyObject *o, void *p)
955{
956 if (o == Py_None) {
957 *(int *)p = DEFAULT_DIR_FD;
958 return 1;
959 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300960 else if (PyIndex_Check(o)) {
961 return _fd_converter(o, (int *)p);
962 }
963 else {
964 PyErr_Format(PyExc_TypeError,
965 "argument should be integer or None, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -0800966 _PyType_Name(Py_TYPE(o)));
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300967 return 0;
968 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700969}
970
Eddie Elizondob3966632019-11-05 07:16:14 -0800971typedef struct {
972 PyObject *billion;
Eddie Elizondob3966632019-11-05 07:16:14 -0800973 PyObject *DirEntryType;
974 PyObject *ScandirIteratorType;
975#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
976 PyObject *SchedParamType;
977#endif
978 PyObject *StatResultType;
979 PyObject *StatVFSResultType;
980 PyObject *TerminalSizeType;
981 PyObject *TimesResultType;
982 PyObject *UnameResultType;
983#if defined(HAVE_WAITID) && !defined(__APPLE__)
984 PyObject *WaitidResultType;
985#endif
986#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
987 PyObject *struct_rusage;
988#endif
989 PyObject *st_mode;
990} _posixstate;
991
Eddie Elizondob3966632019-11-05 07:16:14 -0800992
Hai Shif707d942020-03-16 21:15:01 +0800993static inline _posixstate*
994get_posix_state(PyObject *module)
995{
996 void *state = PyModule_GetState(module);
997 assert(state != NULL);
998 return (_posixstate *)state;
999}
1000
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001/*
1002 * A PyArg_ParseTuple "converter" function
1003 * that handles filesystem paths in the manner
1004 * preferred by the os module.
1005 *
1006 * path_converter accepts (Unicode) strings and their
1007 * subclasses, and bytes and their subclasses. What
1008 * it does with the argument depends on the platform:
1009 *
1010 * * On Windows, if we get a (Unicode) string we
1011 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -07001012 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -07001013 *
1014 * * On all other platforms, strings are encoded
1015 * to bytes using PyUnicode_FSConverter, then we
1016 * extract the char * from the bytes object and
1017 * return that.
1018 *
1019 * path_converter also optionally accepts signed
1020 * integers (representing open file descriptors) instead
1021 * of path strings.
1022 *
1023 * Input fields:
1024 * path.nullable
1025 * If nonzero, the path is permitted to be None.
1026 * path.allow_fd
1027 * If nonzero, the path is permitted to be a file handle
1028 * (a signed int) instead of a string.
1029 * path.function_name
1030 * If non-NULL, path_converter will use that as the name
1031 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -07001032 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001033 * path.argument_name
1034 * If non-NULL, path_converter will use that as the name
1035 * of the parameter in error messages.
1036 * (If path.argument_name is NULL it uses "path".)
1037 *
1038 * Output fields:
1039 * path.wide
1040 * Points to the path if it was expressed as Unicode
1041 * and was not encoded. (Only used on Windows.)
1042 * path.narrow
1043 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -07001044 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +00001045 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -07001046 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001047 * path.fd
1048 * Contains a file descriptor if path.accept_fd was true
1049 * and the caller provided a signed integer instead of any
1050 * sort of string.
1051 *
1052 * WARNING: if your "path" parameter is optional, and is
1053 * unspecified, path_converter will never get called.
1054 * So if you set allow_fd, you *MUST* initialize path.fd = -1
1055 * yourself!
1056 * path.length
1057 * The length of the path in characters, if specified as
1058 * a string.
1059 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +08001060 * The original object passed in (if get a PathLike object,
1061 * the result of PyOS_FSPath() is treated as the original object).
1062 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -07001063 * path.cleanup
1064 * For internal use only. May point to a temporary object.
1065 * (Pay no attention to the man behind the curtain.)
1066 *
1067 * At most one of path.wide or path.narrow will be non-NULL.
1068 * If path was None and path.nullable was set,
1069 * or if path was an integer and path.allow_fd was set,
1070 * both path.wide and path.narrow will be NULL
1071 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +02001072 *
Larry Hastings9cf065c2012-06-22 16:30:09 -07001073 * path_converter takes care to not write to the path_t
1074 * unless it's successful. However it must reset the
1075 * "cleanup" field each time it's called.
1076 *
1077 * Use as follows:
1078 * path_t path;
1079 * memset(&path, 0, sizeof(path));
1080 * PyArg_ParseTuple(args, "O&", path_converter, &path);
1081 * // ... use values from path ...
1082 * path_cleanup(&path);
1083 *
1084 * (Note that if PyArg_Parse fails you don't need to call
1085 * path_cleanup(). However it is safe to do so.)
1086 */
1087typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +01001088 const char *function_name;
1089 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001090 int nullable;
1091 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001092 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -07001093#ifdef MS_WINDOWS
1094 BOOL narrow;
1095#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001096 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001097#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001098 int fd;
1099 Py_ssize_t length;
1100 PyObject *object;
1101 PyObject *cleanup;
1102} path_t;
1103
Steve Dowercc16be82016-09-08 10:35:16 -07001104#ifdef MS_WINDOWS
1105#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1106 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
1107#else
Larry Hastings2f936352014-08-05 14:04:04 +10001108#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
1109 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -07001110#endif
Larry Hastings31826802013-10-19 00:09:25 -07001111
Larry Hastings9cf065c2012-06-22 16:30:09 -07001112static void
Xiang Zhang04316c42017-01-08 23:26:57 +08001113path_cleanup(path_t *path)
1114{
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001115#if !USE_UNICODE_WCHAR_CACHE
1116 wchar_t *wide = (wchar_t *)path->wide;
1117 path->wide = NULL;
1118 PyMem_Free(wide);
1119#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001120 Py_CLEAR(path->object);
1121 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001122}
1123
1124static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001125path_converter(PyObject *o, void *p)
1126{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001127 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +08001128 PyObject *bytes = NULL;
1129 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001130 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001131 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001132#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +08001133 PyObject *wo = NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001134 wchar_t *wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001135#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001136
1137#define FORMAT_EXCEPTION(exc, fmt) \
1138 PyErr_Format(exc, "%s%s" fmt, \
1139 path->function_name ? path->function_name : "", \
1140 path->function_name ? ": " : "", \
1141 path->argument_name ? path->argument_name : "path")
1142
1143 /* Py_CLEANUP_SUPPORTED support */
1144 if (o == NULL) {
1145 path_cleanup(path);
1146 return 1;
1147 }
1148
Brett Cannon3f9183b2016-08-26 14:44:48 -07001149 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +08001150 path->object = path->cleanup = NULL;
1151 /* path->object owns a reference to the original object */
1152 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001153
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001154 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001155 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001156#ifdef MS_WINDOWS
1157 path->narrow = FALSE;
1158#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001159 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001160#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001161 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001162 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001163 }
1164
Brett Cannon3f9183b2016-08-26 14:44:48 -07001165 /* Only call this here so that we don't treat the return value of
1166 os.fspath() as an fd or buffer. */
1167 is_index = path->allow_fd && PyIndex_Check(o);
1168 is_buffer = PyObject_CheckBuffer(o);
1169 is_bytes = PyBytes_Check(o);
1170 is_unicode = PyUnicode_Check(o);
1171
1172 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
1173 /* Inline PyOS_FSPath() for better error messages. */
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001174 PyObject *func, *res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001175
1176 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
1177 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001178 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001179 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001180 res = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001181 Py_DECREF(func);
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001182 if (NULL == res) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001183 goto error_exit;
1184 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001185 else if (PyUnicode_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001186 is_unicode = 1;
1187 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001188 else if (PyBytes_Check(res)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -07001189 is_bytes = 1;
1190 }
1191 else {
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001192 PyErr_Format(PyExc_TypeError,
1193 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -08001194 "not %.200s", _PyType_Name(Py_TYPE(o)),
1195 _PyType_Name(Py_TYPE(res)));
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001196 Py_DECREF(res);
1197 goto error_exit;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001198 }
Pablo Galindo09fbcd62019-02-18 10:46:34 +00001199
1200 /* still owns a reference to the original object */
1201 Py_DECREF(o);
1202 o = res;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001203 }
1204
1205 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001206#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001207#if USE_UNICODE_WCHAR_CACHE
1208_Py_COMP_DIAG_PUSH
1209_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001210 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001211_Py_COMP_DIAG_POP
1212#else /* USE_UNICODE_WCHAR_CACHE */
1213 wide = PyUnicode_AsWideCharString(o, &length);
1214#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner59799a82013-11-13 14:17:30 +01001215 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001216 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001217 }
Victor Stinner59799a82013-11-13 14:17:30 +01001218 if (length > 32767) {
1219 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001220 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001221 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001222 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001223 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001224 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001225 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001226
1227 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001228 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001229 path->fd = -1;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001230#if !USE_UNICODE_WCHAR_CACHE
1231 wide = NULL;
1232#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001233 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001234#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001235 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001236 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001237 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001238#endif
1239 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001240 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001241 bytes = o;
1242 Py_INCREF(bytes);
1243 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001244 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001245 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001246 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001247 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1248 "%s%s%s should be %s, not %.200s",
1249 path->function_name ? path->function_name : "",
1250 path->function_name ? ": " : "",
1251 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001252 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1253 "integer or None" :
1254 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1255 path->nullable ? "string, bytes, os.PathLike or None" :
1256 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001257 _PyType_Name(Py_TYPE(o)))) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001258 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001259 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001260 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001261 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001262 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001263 }
1264 }
Steve Dowercc16be82016-09-08 10:35:16 -07001265 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001266 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001267 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001268 }
1269 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001270#ifdef MS_WINDOWS
1271 path->narrow = FALSE;
1272#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001273 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001274#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001275 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001276 }
1277 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001278 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001279 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1280 path->function_name ? path->function_name : "",
1281 path->function_name ? ": " : "",
1282 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001283 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1284 "integer or None" :
1285 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1286 path->nullable ? "string, bytes, os.PathLike or None" :
1287 "string, bytes or os.PathLike",
Eddie Elizondob3966632019-11-05 07:16:14 -08001288 _PyType_Name(Py_TYPE(o)));
Xiang Zhang04316c42017-01-08 23:26:57 +08001289 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001290 }
1291
Larry Hastings9cf065c2012-06-22 16:30:09 -07001292 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001293 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001294 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001295 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001296 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001297 }
1298
Steve Dowercc16be82016-09-08 10:35:16 -07001299#ifdef MS_WINDOWS
1300 wo = PyUnicode_DecodeFSDefaultAndSize(
1301 narrow,
1302 length
1303 );
1304 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001305 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001306 }
1307
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001308#if USE_UNICODE_WCHAR_CACHE
1309_Py_COMP_DIAG_PUSH
1310_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Xiang Zhang04316c42017-01-08 23:26:57 +08001311 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001312_Py_COMP_DIAG_POP
1313#else /* USE_UNICODE_WCHAR_CACHE */
1314 wide = PyUnicode_AsWideCharString(wo, &length);
1315 Py_DECREF(wo);
1316#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001317 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001318 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001319 }
1320 if (length > 32767) {
1321 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001322 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001323 }
1324 if (wcslen(wide) != length) {
1325 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001326 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001327 }
1328 path->wide = wide;
1329 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001330 Py_DECREF(bytes);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001331#if USE_UNICODE_WCHAR_CACHE
1332 path->cleanup = wo;
1333#else /* USE_UNICODE_WCHAR_CACHE */
1334 wide = NULL;
1335#endif /* USE_UNICODE_WCHAR_CACHE */
Steve Dowercc16be82016-09-08 10:35:16 -07001336#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001337 path->wide = NULL;
1338 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001339 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001340 /* Still a reference owned by path->object, don't have to
1341 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001342 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001343 }
1344 else {
1345 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001346 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001347#endif
1348 path->fd = -1;
1349
1350 success_exit:
1351 path->length = length;
1352 path->object = o;
1353 return Py_CLEANUP_SUPPORTED;
1354
1355 error_exit:
1356 Py_XDECREF(o);
1357 Py_XDECREF(bytes);
1358#ifdef MS_WINDOWS
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001359#if USE_UNICODE_WCHAR_CACHE
Xiang Zhang04316c42017-01-08 23:26:57 +08001360 Py_XDECREF(wo);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +03001361#else /* USE_UNICODE_WCHAR_CACHE */
1362 PyMem_Free(wide);
1363#endif /* USE_UNICODE_WCHAR_CACHE */
Xiang Zhang04316c42017-01-08 23:26:57 +08001364#endif
1365 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001366}
1367
1368static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001369argument_unavailable_error(const char *function_name, const char *argument_name)
1370{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001371 PyErr_Format(PyExc_NotImplementedError,
1372 "%s%s%s unavailable on this platform",
1373 (function_name != NULL) ? function_name : "",
1374 (function_name != NULL) ? ": ": "",
1375 argument_name);
1376}
1377
1378static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001379dir_fd_unavailable(PyObject *o, void *p)
1380{
1381 int dir_fd;
1382 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001383 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001384 if (dir_fd != DEFAULT_DIR_FD) {
1385 argument_unavailable_error(NULL, "dir_fd");
1386 return 0;
1387 }
1388 *(int *)p = dir_fd;
1389 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001390}
1391
1392static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001393fd_specified(const char *function_name, int fd)
1394{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001395 if (fd == -1)
1396 return 0;
1397
1398 argument_unavailable_error(function_name, "fd");
1399 return 1;
1400}
1401
1402static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001403follow_symlinks_specified(const char *function_name, int follow_symlinks)
1404{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001405 if (follow_symlinks)
1406 return 0;
1407
1408 argument_unavailable_error(function_name, "follow_symlinks");
1409 return 1;
1410}
1411
1412static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001413path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1414{
Steve Dowercc16be82016-09-08 10:35:16 -07001415 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1416#ifndef MS_WINDOWS
1417 && !path->narrow
1418#endif
1419 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001420 PyErr_Format(PyExc_ValueError,
1421 "%s: can't specify dir_fd without matching path",
1422 function_name);
1423 return 1;
1424 }
1425 return 0;
1426}
1427
1428static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001429dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1430{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001431 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1432 PyErr_Format(PyExc_ValueError,
1433 "%s: can't specify both dir_fd and fd",
1434 function_name);
1435 return 1;
1436 }
1437 return 0;
1438}
1439
1440static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001441fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1442 int follow_symlinks)
1443{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001444 if ((fd > 0) && (!follow_symlinks)) {
1445 PyErr_Format(PyExc_ValueError,
1446 "%s: cannot use fd and follow_symlinks together",
1447 function_name);
1448 return 1;
1449 }
1450 return 0;
1451}
1452
1453static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001454dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1455 int follow_symlinks)
1456{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001457 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1458 PyErr_Format(PyExc_ValueError,
1459 "%s: cannot use dir_fd and follow_symlinks together",
1460 function_name);
1461 return 1;
1462 }
1463 return 0;
1464}
1465
Larry Hastings2f936352014-08-05 14:04:04 +10001466#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001467 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001468#else
Larry Hastings2f936352014-08-05 14:04:04 +10001469 typedef off_t Py_off_t;
1470#endif
1471
1472static int
1473Py_off_t_converter(PyObject *arg, void *addr)
1474{
1475#ifdef HAVE_LARGEFILE_SUPPORT
1476 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1477#else
1478 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001479#endif
1480 if (PyErr_Occurred())
1481 return 0;
1482 return 1;
1483}
Larry Hastings2f936352014-08-05 14:04:04 +10001484
1485static PyObject *
1486PyLong_FromPy_off_t(Py_off_t offset)
1487{
1488#ifdef HAVE_LARGEFILE_SUPPORT
1489 return PyLong_FromLongLong(offset);
1490#else
1491 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001492#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001493}
1494
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001495#ifdef HAVE_SIGSET_T
1496/* Convert an iterable of integers to a sigset.
1497 Return 1 on success, return 0 and raise an exception on error. */
1498int
1499_Py_Sigset_Converter(PyObject *obj, void *addr)
1500{
1501 sigset_t *mask = (sigset_t *)addr;
1502 PyObject *iterator, *item;
1503 long signum;
1504 int overflow;
1505
Rémi Lapeyref0900192019-05-04 01:30:53 +02001506 // The extra parens suppress the unreachable-code warning with clang on MacOS
1507 if (sigemptyset(mask) < (0)) {
Serhiy Storchakad54cfb12018-05-08 07:48:50 +03001508 /* Probably only if mask == NULL. */
1509 PyErr_SetFromErrno(PyExc_OSError);
1510 return 0;
1511 }
1512
1513 iterator = PyObject_GetIter(obj);
1514 if (iterator == NULL) {
1515 return 0;
1516 }
1517
1518 while ((item = PyIter_Next(iterator)) != NULL) {
1519 signum = PyLong_AsLongAndOverflow(item, &overflow);
1520 Py_DECREF(item);
1521 if (signum <= 0 || signum >= NSIG) {
1522 if (overflow || signum != -1 || !PyErr_Occurred()) {
1523 PyErr_Format(PyExc_ValueError,
1524 "signal number %ld out of range", signum);
1525 }
1526 goto error;
1527 }
1528 if (sigaddset(mask, (int)signum)) {
1529 if (errno != EINVAL) {
1530 /* Probably impossible */
1531 PyErr_SetFromErrno(PyExc_OSError);
1532 goto error;
1533 }
1534 /* For backwards compatibility, allow idioms such as
1535 * `range(1, NSIG)` but warn about invalid signal numbers
1536 */
1537 const char msg[] =
1538 "invalid signal number %ld, please use valid_signals()";
1539 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) {
1540 goto error;
1541 }
1542 }
1543 }
1544 if (!PyErr_Occurred()) {
1545 Py_DECREF(iterator);
1546 return 1;
1547 }
1548
1549error:
1550 Py_DECREF(iterator);
1551 return 0;
1552}
1553#endif /* HAVE_SIGSET_T */
1554
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001555#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001556
1557static int
Brian Curtind25aef52011-06-13 15:16:04 -05001558win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001559{
Martin Panter70214ad2016-08-04 02:38:59 +00001560 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1561 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001562 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001563
1564 if (0 == DeviceIoControl(
1565 reparse_point_handle,
1566 FSCTL_GET_REPARSE_POINT,
1567 NULL, 0, /* in buffer */
1568 target_buffer, sizeof(target_buffer),
1569 &n_bytes_returned,
1570 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001571 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001572
1573 if (reparse_tag)
1574 *reparse_tag = rdb->ReparseTag;
1575
Brian Curtind25aef52011-06-13 15:16:04 -05001576 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001577}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001578
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001579#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001580
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001581/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001582#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001583/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001584** environ directly, we must obtain it with _NSGetEnviron(). See also
1585** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001586*/
1587#include <crt_externs.h>
pxinwrf2d7ac72019-05-21 18:46:37 +08001588#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001589extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001590#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001591
Barry Warsaw53699e91996-12-10 23:23:01 +00001592static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001593convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001594{
Victor Stinner8c62be82010-05-06 00:08:46 +00001595 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001596#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001597 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001598#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001599 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001600#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001601
Victor Stinner8c62be82010-05-06 00:08:46 +00001602 d = PyDict_New();
1603 if (d == NULL)
1604 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001605#ifdef MS_WINDOWS
1606 /* _wenviron must be initialized in this way if the program is started
1607 through main() instead of wmain(). */
1608 _wgetenv(L"");
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001609 e = _wenviron;
Benoit Hudson723f71a2019-12-06 14:15:03 -05001610#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
1611 /* environ is not accessible as an extern in a shared object on OSX; use
1612 _NSGetEnviron to resolve it. The value changes if you add environment
1613 variables between calls to Py_Initialize, so don't cache the value. */
1614 e = *_NSGetEnviron();
Victor Stinner8c62be82010-05-06 00:08:46 +00001615#else
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001616 e = environ;
1617#endif
1618 if (e == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00001619 return d;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001620 for (; *e != NULL; e++) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001621 PyObject *k;
1622 PyObject *v;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001623#ifdef MS_WINDOWS
1624 const wchar_t *p = wcschr(*e, L'=');
1625#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001626 const char *p = strchr(*e, '=');
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001627#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001628 if (p == NULL)
1629 continue;
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001630#ifdef MS_WINDOWS
1631 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1632#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001633 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001634#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001635 if (k == NULL) {
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001636 Py_DECREF(d);
1637 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001638 }
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001639#ifdef MS_WINDOWS
1640 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1641#else
Victor Stinner84ae1182010-05-06 22:05:07 +00001642 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001643#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001644 if (v == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00001645 Py_DECREF(k);
Serhiy Storchaka6fef0f12018-12-10 12:10:56 +02001646 Py_DECREF(d);
1647 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001648 }
Serhiy Storchakab510e102020-10-26 12:47:57 +02001649 if (PyDict_SetDefault(d, k, v) == NULL) {
1650 Py_DECREF(v);
1651 Py_DECREF(k);
1652 Py_DECREF(d);
1653 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001654 }
1655 Py_DECREF(k);
1656 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001657 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001658 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001659}
1660
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001661/* Set a POSIX-specific error from errno, and return NULL */
1662
Barry Warsawd58d7641998-07-23 16:14:40 +00001663static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001664posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001665{
Victor Stinner8c62be82010-05-06 00:08:46 +00001666 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001667}
Mark Hammondef8b6542001-05-13 08:04:26 +00001668
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001669#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001670static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001671win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001672{
Victor Stinner8c62be82010-05-06 00:08:46 +00001673 /* XXX We should pass the function name along in the future.
1674 (winreg.c also wants to pass the function name.)
1675 This would however require an additional param to the
1676 Windows error object, which is non-trivial.
1677 */
1678 errno = GetLastError();
1679 if (filename)
1680 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1681 else
1682 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001683}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001684
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001685static PyObject *
Steve Dower2438cdf2019-03-29 16:37:16 -07001686win32_error_object_err(const char* function, PyObject* filename, DWORD err)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001687{
1688 /* XXX - see win32_error for comments on 'function' */
Victor Stinnereb5657a2011-09-30 01:44:27 +02001689 if (filename)
1690 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001691 PyExc_OSError,
Steve Dower2438cdf2019-03-29 16:37:16 -07001692 err,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001693 filename);
1694 else
Steve Dower2438cdf2019-03-29 16:37:16 -07001695 return PyErr_SetFromWindowsErr(err);
1696}
1697
1698static PyObject *
1699win32_error_object(const char* function, PyObject* filename)
1700{
1701 errno = GetLastError();
1702 return win32_error_object_err(function, filename, errno);
Victor Stinnereb5657a2011-09-30 01:44:27 +02001703}
1704
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001705#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001706
Larry Hastings9cf065c2012-06-22 16:30:09 -07001707static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001708posix_path_object_error(PyObject *path)
1709{
1710 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1711}
1712
1713static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001714path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001715{
1716#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001717 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1718 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001719#else
Alexey Izbyshev83460312018-10-20 03:28:22 +03001720 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001721#endif
1722}
1723
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001724static PyObject *
1725path_object_error2(PyObject *path, PyObject *path2)
1726{
1727#ifdef MS_WINDOWS
1728 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1729 PyExc_OSError, 0, path, path2);
1730#else
1731 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1732#endif
1733}
1734
1735static PyObject *
1736path_error(path_t *path)
1737{
1738 return path_object_error(path->object);
1739}
Larry Hastings31826802013-10-19 00:09:25 -07001740
Larry Hastingsb0827312014-02-09 22:05:19 -08001741static PyObject *
Alexey Izbyshev83460312018-10-20 03:28:22 +03001742posix_path_error(path_t *path)
1743{
1744 return posix_path_object_error(path->object);
1745}
1746
1747static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001748path_error2(path_t *path, path_t *path2)
1749{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001750 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001751}
1752
1753
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001754/* POSIX generic methods */
1755
Larry Hastings2f936352014-08-05 14:04:04 +10001756static PyObject *
1757posix_fildes_fd(int fd, int (*func)(int))
1758{
1759 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001760 int async_err = 0;
1761
1762 do {
1763 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001764 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001765 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001766 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001767 Py_END_ALLOW_THREADS
1768 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1769 if (res != 0)
1770 return (!async_err) ? posix_error() : NULL;
1771 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001772}
Guido van Rossum21142a01999-01-08 21:05:37 +00001773
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001774
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001775#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001776/* This is a reimplementation of the C library's chdir function,
1777 but one that produces Win32 errors instead of DOS error codes.
1778 chdir is essentially a wrapper around SetCurrentDirectory; however,
1779 it also needs to set "magic" environment variables indicating
1780 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001781static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001782win32_wchdir(LPCWSTR path)
1783{
Victor Stinnered537822015-12-13 21:40:26 +01001784 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 int result;
1786 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001787
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 if(!SetCurrentDirectoryW(path))
1789 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001790 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001791 if (!result)
1792 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001793 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001794 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001795 if (!new_path) {
1796 SetLastError(ERROR_OUTOFMEMORY);
1797 return FALSE;
1798 }
1799 result = GetCurrentDirectoryW(result, new_path);
1800 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001801 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001802 return FALSE;
1803 }
1804 }
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001805 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1806 wcsncmp(new_path, L"//", 2) == 0);
1807 if (!is_unc_like_path) {
1808 env[1] = new_path[0];
1809 result = SetEnvironmentVariableW(env, new_path);
1810 }
Victor Stinnered537822015-12-13 21:40:26 +01001811 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001812 PyMem_RawFree(new_path);
Alexey Izbyshev3e197c72018-03-01 12:13:56 +03001813 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001814}
1815#endif
1816
Martin v. Löwis14694662006-02-03 12:54:16 +00001817#ifdef MS_WINDOWS
1818/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1819 - time stamps are restricted to second resolution
1820 - file modification times suffer from forth-and-back conversions between
1821 UTC and local time
1822 Therefore, we implement our own stat, based on the Win32 API directly.
1823*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001824#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001825#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001826#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001827
Victor Stinner6036e442015-03-08 01:58:04 +01001828static void
Steve Dowercc16be82016-09-08 10:35:16 -07001829find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1830 BY_HANDLE_FILE_INFORMATION *info,
1831 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001832{
1833 memset(info, 0, sizeof(*info));
1834 info->dwFileAttributes = pFileData->dwFileAttributes;
1835 info->ftCreationTime = pFileData->ftCreationTime;
1836 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1837 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1838 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1839 info->nFileSizeLow = pFileData->nFileSizeLow;
1840/* info->nNumberOfLinks = 1; */
1841 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1842 *reparse_tag = pFileData->dwReserved0;
1843 else
1844 *reparse_tag = 0;
1845}
1846
Guido van Rossumd8faa362007-04-27 19:54:29 +00001847static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001848attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001849{
Victor Stinner8c62be82010-05-06 00:08:46 +00001850 HANDLE hFindFile;
1851 WIN32_FIND_DATAW FileData;
1852 hFindFile = FindFirstFileW(pszFile, &FileData);
1853 if (hFindFile == INVALID_HANDLE_VALUE)
1854 return FALSE;
1855 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001856 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001857 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001858}
1859
Brian Curtind25aef52011-06-13 15:16:04 -05001860static int
Steve Dowercc16be82016-09-08 10:35:16 -07001861win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001862 BOOL traverse)
1863{
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001864 HANDLE hFile;
1865 BY_HANDLE_FILE_INFORMATION fileInfo;
1866 FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 };
1867 DWORD fileType, error;
1868 BOOL isUnhandledTag = FALSE;
1869 int retval = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001870
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001871 DWORD access = FILE_READ_ATTRIBUTES;
1872 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
1873 if (!traverse) {
1874 flags |= FILE_FLAG_OPEN_REPARSE_POINT;
1875 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001876
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001877 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001878 if (hFile == INVALID_HANDLE_VALUE) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001879 /* Either the path doesn't exist, or the caller lacks access. */
1880 error = GetLastError();
1881 switch (error) {
1882 case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */
1883 case ERROR_SHARING_VIOLATION: /* It's a paging file. */
1884 /* Try reading the parent directory. */
1885 if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) {
1886 /* Cannot read the parent directory. */
1887 SetLastError(error);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001888 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001889 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001890 if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1891 if (traverse ||
1892 !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1893 /* The stat call has to traverse but cannot, so fail. */
1894 SetLastError(error);
Brian Curtind25aef52011-06-13 15:16:04 -05001895 return -1;
Mark Becwarb82bfac2019-02-02 16:08:23 -05001896 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001897 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001898 break;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001899
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001900 case ERROR_INVALID_PARAMETER:
1901 /* \\.\con requires read or write access. */
1902 hFile = CreateFileW(path, access | GENERIC_READ,
1903 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1904 OPEN_EXISTING, flags, NULL);
1905 if (hFile == INVALID_HANDLE_VALUE) {
1906 SetLastError(error);
1907 return -1;
1908 }
1909 break;
1910
1911 case ERROR_CANT_ACCESS_FILE:
1912 /* bpo37834: open unhandled reparse points if traverse fails. */
1913 if (traverse) {
1914 traverse = FALSE;
1915 isUnhandledTag = TRUE;
1916 hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING,
1917 flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
1918 }
1919 if (hFile == INVALID_HANDLE_VALUE) {
1920 SetLastError(error);
1921 return -1;
1922 }
1923 break;
1924
1925 default:
1926 return -1;
1927 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001928 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001929
1930 if (hFile != INVALID_HANDLE_VALUE) {
1931 /* Handle types other than files on disk. */
1932 fileType = GetFileType(hFile);
1933 if (fileType != FILE_TYPE_DISK) {
1934 if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) {
1935 retval = -1;
1936 goto cleanup;
1937 }
1938 DWORD fileAttributes = GetFileAttributesW(path);
1939 memset(result, 0, sizeof(*result));
1940 if (fileAttributes != INVALID_FILE_ATTRIBUTES &&
1941 fileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1942 /* \\.\pipe\ or \\.\mailslot\ */
1943 result->st_mode = _S_IFDIR;
1944 } else if (fileType == FILE_TYPE_CHAR) {
1945 /* \\.\nul */
1946 result->st_mode = _S_IFCHR;
1947 } else if (fileType == FILE_TYPE_PIPE) {
1948 /* \\.\pipe\spam */
1949 result->st_mode = _S_IFIFO;
1950 }
1951 /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */
1952 goto cleanup;
1953 }
1954
1955 /* Query the reparse tag, and traverse a non-link. */
1956 if (!traverse) {
1957 if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo,
1958 &tagInfo, sizeof(tagInfo))) {
1959 /* Allow devices that do not support FileAttributeTagInfo. */
1960 switch (GetLastError()) {
1961 case ERROR_INVALID_PARAMETER:
1962 case ERROR_INVALID_FUNCTION:
1963 case ERROR_NOT_SUPPORTED:
1964 tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1965 tagInfo.ReparseTag = 0;
1966 break;
1967 default:
1968 retval = -1;
1969 goto cleanup;
1970 }
1971 } else if (tagInfo.FileAttributes &
1972 FILE_ATTRIBUTE_REPARSE_POINT) {
1973 if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) {
1974 if (isUnhandledTag) {
1975 /* Traversing previously failed for either this link
1976 or its target. */
1977 SetLastError(ERROR_CANT_ACCESS_FILE);
1978 retval = -1;
1979 goto cleanup;
1980 }
1981 /* Traverse a non-link, but not if traversing already failed
1982 for an unhandled tag. */
1983 } else if (!isUnhandledTag) {
1984 CloseHandle(hFile);
1985 return win32_xstat_impl(path, result, TRUE);
1986 }
1987 }
1988 }
1989
1990 if (!GetFileInformationByHandle(hFile, &fileInfo)) {
1991 switch (GetLastError()) {
1992 case ERROR_INVALID_PARAMETER:
1993 case ERROR_INVALID_FUNCTION:
1994 case ERROR_NOT_SUPPORTED:
Steve Dower772ec0f2019-09-04 14:42:54 -07001995 /* Volumes and physical disks are block devices, e.g.
1996 \\.\C: and \\.\PhysicalDrive0. */
1997 memset(result, 0, sizeof(*result));
1998 result->st_mode = 0x6000; /* S_IFBLK */
Steve Dowerdf2d4a62019-08-21 15:27:33 -07001999 goto cleanup;
2000 }
Steve Dower772ec0f2019-09-04 14:42:54 -07002001 retval = -1;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002002 goto cleanup;
2003 }
2004 }
2005
2006 _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result);
2007
2008 if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
2009 /* Fix the file execute permissions. This hack sets S_IEXEC if
2010 the filename has an extension that is commonly used by files
2011 that CreateProcessW can execute. A real implementation calls
2012 GetSecurityInfo, OpenThreadToken/OpenProcessToken, and
2013 AccessCheck to check for generic read, write, and execute
2014 access. */
2015 const wchar_t *fileExtension = wcsrchr(path, '.');
2016 if (fileExtension) {
2017 if (_wcsicmp(fileExtension, L".exe") == 0 ||
2018 _wcsicmp(fileExtension, L".bat") == 0 ||
2019 _wcsicmp(fileExtension, L".cmd") == 0 ||
2020 _wcsicmp(fileExtension, L".com") == 0) {
2021 result->st_mode |= 0111;
2022 }
2023 }
2024 }
2025
2026cleanup:
2027 if (hFile != INVALID_HANDLE_VALUE) {
Steve Dower772ec0f2019-09-04 14:42:54 -07002028 /* Preserve last error if we are failing */
2029 error = retval ? GetLastError() : 0;
2030 if (!CloseHandle(hFile)) {
2031 retval = -1;
2032 } else if (retval) {
2033 /* Restore last error */
2034 SetLastError(error);
2035 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002036 }
2037
2038 return retval;
Brian Curtinf5e76d02010-11-24 13:14:05 +00002039}
2040
2041static int
Steve Dowercc16be82016-09-08 10:35:16 -07002042win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00002043{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002044 /* Protocol violation: we explicitly clear errno, instead of
2045 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05002046 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002047 errno = 0;
2048 return code;
2049}
Brian Curtind25aef52011-06-13 15:16:04 -05002050/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00002051
2052 In Posix, stat automatically traverses symlinks and returns the stat
2053 structure for the target. In Windows, the equivalent GetFileAttributes by
2054 default does not traverse symlinks and instead returns attributes for
2055 the symlink.
2056
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002057 Instead, we will open the file (which *does* traverse symlinks by default)
2058 and GetFileInformationByHandle(). */
Brian Curtind40e6f72010-07-08 21:39:08 +00002059
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002060static int
Steve Dowercc16be82016-09-08 10:35:16 -07002061win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00002062{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002063 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00002064}
2065
Victor Stinner8c62be82010-05-06 00:08:46 +00002066static int
Steve Dowercc16be82016-09-08 10:35:16 -07002067win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00002068{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002069 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00002070}
2071
Martin v. Löwis14694662006-02-03 12:54:16 +00002072#endif /* MS_WINDOWS */
2073
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002074PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002075"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002076This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002077 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002078or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
2079\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002080Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
2081or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002082\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002083See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002084
2085static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 {"st_mode", "protection bits"},
2087 {"st_ino", "inode"},
2088 {"st_dev", "device"},
2089 {"st_nlink", "number of hard links"},
2090 {"st_uid", "user ID of owner"},
2091 {"st_gid", "group ID of owner"},
2092 {"st_size", "total size, in bytes"},
2093 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
2094 {NULL, "integer time of last access"},
2095 {NULL, "integer time of last modification"},
2096 {NULL, "integer time of last change"},
2097 {"st_atime", "time of last access"},
2098 {"st_mtime", "time of last modification"},
2099 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07002100 {"st_atime_ns", "time of last access in nanoseconds"},
2101 {"st_mtime_ns", "time of last modification in nanoseconds"},
2102 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002103#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002104 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002105#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002106#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002107 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002108#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002109#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002110 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002111#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002112#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002114#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002115#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002116 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002117#endif
2118#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002119 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002120#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002121#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2122 {"st_file_attributes", "Windows file attribute bits"},
2123#endif
jcea6c51d512018-01-28 14:00:08 +01002124#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2125 {"st_fstype", "Type of filesystem"},
2126#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002127#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2128 {"st_reparse_tag", "Windows reparse tag"},
2129#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002130 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002131};
2132
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002133#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002134#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002135#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002136#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002137#endif
2138
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002139#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002140#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2141#else
2142#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2143#endif
2144
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002145#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002146#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2147#else
2148#define ST_RDEV_IDX ST_BLOCKS_IDX
2149#endif
2150
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002151#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2152#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2153#else
2154#define ST_FLAGS_IDX ST_RDEV_IDX
2155#endif
2156
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002157#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002158#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002159#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002160#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002161#endif
2162
2163#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2164#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2165#else
2166#define ST_BIRTHTIME_IDX ST_GEN_IDX
2167#endif
2168
Zachary Ware63f277b2014-06-19 09:46:37 -05002169#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2170#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
2171#else
2172#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
2173#endif
2174
jcea6c51d512018-01-28 14:00:08 +01002175#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2176#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
2177#else
2178#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
2179#endif
2180
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002181#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2182#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1)
2183#else
2184#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX
2185#endif
2186
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002187static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002188 "stat_result", /* name */
2189 stat_result__doc__, /* doc */
2190 stat_result_fields,
2191 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002192};
2193
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002194PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002195"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2196This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002197 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002198or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002199\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002200See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002201
2202static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002203 {"f_bsize", },
2204 {"f_frsize", },
2205 {"f_blocks", },
2206 {"f_bfree", },
2207 {"f_bavail", },
2208 {"f_files", },
2209 {"f_ffree", },
2210 {"f_favail", },
2211 {"f_flag", },
2212 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01002213 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00002214 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002215};
2216
2217static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002218 "statvfs_result", /* name */
2219 statvfs_result__doc__, /* doc */
2220 statvfs_result_fields,
2221 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002222};
2223
Ross Lagerwall7807c352011-03-17 20:20:30 +02002224#if defined(HAVE_WAITID) && !defined(__APPLE__)
2225PyDoc_STRVAR(waitid_result__doc__,
2226"waitid_result: Result from waitid.\n\n\
2227This object may be accessed either as a tuple of\n\
2228 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2229or via the attributes si_pid, si_uid, and so on.\n\
2230\n\
2231See os.waitid for more information.");
2232
2233static PyStructSequence_Field waitid_result_fields[] = {
2234 {"si_pid", },
2235 {"si_uid", },
2236 {"si_signo", },
2237 {"si_status", },
2238 {"si_code", },
2239 {0}
2240};
2241
2242static PyStructSequence_Desc waitid_result_desc = {
2243 "waitid_result", /* name */
2244 waitid_result__doc__, /* doc */
2245 waitid_result_fields,
2246 5
2247};
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002248#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002249static newfunc structseq_new;
2250
2251static PyObject *
2252statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2253{
Victor Stinner8c62be82010-05-06 00:08:46 +00002254 PyStructSequence *result;
2255 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002256
Victor Stinner8c62be82010-05-06 00:08:46 +00002257 result = (PyStructSequence*)structseq_new(type, args, kwds);
2258 if (!result)
2259 return NULL;
2260 /* If we have been initialized from a tuple,
2261 st_?time might be set to None. Initialize it
2262 from the int slots. */
2263 for (i = 7; i <= 9; i++) {
2264 if (result->ob_item[i+3] == Py_None) {
2265 Py_DECREF(Py_None);
2266 Py_INCREF(result->ob_item[i]);
2267 result->ob_item[i+3] = result->ob_item[i];
2268 }
2269 }
2270 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002271}
2272
Eddie Elizondob3966632019-11-05 07:16:14 -08002273static int
2274_posix_clear(PyObject *module)
2275{
Victor Stinner97f33c32020-05-14 18:05:58 +02002276 _posixstate *state = get_posix_state(module);
2277 Py_CLEAR(state->billion);
2278 Py_CLEAR(state->DirEntryType);
2279 Py_CLEAR(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002280#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002281 Py_CLEAR(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002282#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002283 Py_CLEAR(state->StatResultType);
2284 Py_CLEAR(state->StatVFSResultType);
2285 Py_CLEAR(state->TerminalSizeType);
2286 Py_CLEAR(state->TimesResultType);
2287 Py_CLEAR(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002288#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002289 Py_CLEAR(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002290#endif
2291#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002292 Py_CLEAR(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002293#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002294 Py_CLEAR(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002295 return 0;
2296}
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002297
Eddie Elizondob3966632019-11-05 07:16:14 -08002298static int
2299_posix_traverse(PyObject *module, visitproc visit, void *arg)
2300{
Victor Stinner97f33c32020-05-14 18:05:58 +02002301 _posixstate *state = get_posix_state(module);
2302 Py_VISIT(state->billion);
2303 Py_VISIT(state->DirEntryType);
2304 Py_VISIT(state->ScandirIteratorType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002305#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Victor Stinner97f33c32020-05-14 18:05:58 +02002306 Py_VISIT(state->SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002307#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002308 Py_VISIT(state->StatResultType);
2309 Py_VISIT(state->StatVFSResultType);
2310 Py_VISIT(state->TerminalSizeType);
2311 Py_VISIT(state->TimesResultType);
2312 Py_VISIT(state->UnameResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002313#if defined(HAVE_WAITID) && !defined(__APPLE__)
Victor Stinner97f33c32020-05-14 18:05:58 +02002314 Py_VISIT(state->WaitidResultType);
Eddie Elizondob3966632019-11-05 07:16:14 -08002315#endif
2316#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +02002317 Py_VISIT(state->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08002318#endif
Victor Stinner97f33c32020-05-14 18:05:58 +02002319 Py_VISIT(state->st_mode);
Eddie Elizondob3966632019-11-05 07:16:14 -08002320 return 0;
2321}
2322
2323static void
2324_posix_free(void *module)
2325{
2326 _posix_clear((PyObject *)module);
2327}
Larry Hastings6fe20b32012-04-19 15:07:49 -07002328
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002329static void
Victor Stinner1c2fa782020-05-10 11:05:29 +02002330fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002331{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002332 PyObject *s = _PyLong_FromTime_t(sec);
2333 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2334 PyObject *s_in_ns = NULL;
2335 PyObject *ns_total = NULL;
2336 PyObject *float_s = NULL;
2337
2338 if (!(s && ns_fractional))
2339 goto exit;
2340
Victor Stinner1c2fa782020-05-10 11:05:29 +02002341 s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion);
Larry Hastings6fe20b32012-04-19 15:07:49 -07002342 if (!s_in_ns)
2343 goto exit;
2344
2345 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2346 if (!ns_total)
2347 goto exit;
2348
Victor Stinner01b5aab2017-10-24 02:02:00 -07002349 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2350 if (!float_s) {
2351 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07002352 }
2353
2354 PyStructSequence_SET_ITEM(v, index, s);
2355 PyStructSequence_SET_ITEM(v, index+3, float_s);
2356 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2357 s = NULL;
2358 float_s = NULL;
2359 ns_total = NULL;
2360exit:
2361 Py_XDECREF(s);
2362 Py_XDECREF(ns_fractional);
2363 Py_XDECREF(s_in_ns);
2364 Py_XDECREF(ns_total);
2365 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002366}
2367
Tim Peters5aa91602002-01-30 05:46:57 +00002368/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002369 (used by posix_stat() and posix_fstat()) */
2370static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +02002371_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002372{
Victor Stinner8c62be82010-05-06 00:08:46 +00002373 unsigned long ansec, mnsec, cnsec;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002374 PyObject *StatResultType = get_posix_state(module)->StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08002375 PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +00002376 if (v == NULL)
2377 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002378
Victor Stinner8c62be82010-05-06 00:08:46 +00002379 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002380 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002381 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002382#ifdef MS_WINDOWS
2383 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002384#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002385 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002386#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002387 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002388#if defined(MS_WINDOWS)
2389 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2390 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2391#else
2392 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2393 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2394#endif
xdegaye50e86032017-05-22 11:15:08 +02002395 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2396 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002397
Martin v. Löwis14694662006-02-03 12:54:16 +00002398#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002399 ansec = st->st_atim.tv_nsec;
2400 mnsec = st->st_mtim.tv_nsec;
2401 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002402#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002403 ansec = st->st_atimespec.tv_nsec;
2404 mnsec = st->st_mtimespec.tv_nsec;
2405 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002406#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002407 ansec = st->st_atime_nsec;
2408 mnsec = st->st_mtime_nsec;
2409 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002410#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002411 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002412#endif
Victor Stinner1c2fa782020-05-10 11:05:29 +02002413 fill_time(module, v, 7, st->st_atime, ansec);
2414 fill_time(module, v, 8, st->st_mtime, mnsec);
2415 fill_time(module, v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002416
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002417#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002418 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2419 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002420#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002421#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002422 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2423 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002424#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002425#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002426 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2427 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002428#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002429#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002430 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2431 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002432#endif
2433#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002434 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002435 PyObject *val;
2436 unsigned long bsec,bnsec;
2437 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002438#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002439 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002440#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002441 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002442#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002443 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002444 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2445 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002446 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002447#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002448#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002449 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2450 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002451#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002452#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2453 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2454 PyLong_FromUnsignedLong(st->st_file_attributes));
2455#endif
jcea6c51d512018-01-28 14:00:08 +01002456#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2457 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2458 PyUnicode_FromString(st->st_fstype));
2459#endif
Steve Dowerdf2d4a62019-08-21 15:27:33 -07002460#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG
2461 PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX,
2462 PyLong_FromUnsignedLong(st->st_reparse_tag));
2463#endif
Fred Drake699f3522000-06-29 21:12:41 +00002464
Victor Stinner8c62be82010-05-06 00:08:46 +00002465 if (PyErr_Occurred()) {
2466 Py_DECREF(v);
2467 return NULL;
2468 }
Fred Drake699f3522000-06-29 21:12:41 +00002469
Victor Stinner8c62be82010-05-06 00:08:46 +00002470 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002471}
2472
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002473/* POSIX methods */
2474
Guido van Rossum94f6f721999-01-06 18:42:14 +00002475
2476static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02002477posix_do_stat(PyObject *module, const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002478 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002479{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002480 STRUCT_STAT st;
2481 int result;
2482
Ronald Oussoren41761932020-11-08 10:05:27 +01002483#ifdef HAVE_FSTATAT
2484 int fstatat_unavailable = 0;
2485#endif
2486
Larry Hastings9cf065c2012-06-22 16:30:09 -07002487#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2488 if (follow_symlinks_specified(function_name, follow_symlinks))
2489 return NULL;
2490#endif
2491
2492 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2493 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2494 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2495 return NULL;
2496
2497 Py_BEGIN_ALLOW_THREADS
2498 if (path->fd != -1)
2499 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002500#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002501 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002502 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002503 else
Steve Dowercc16be82016-09-08 10:35:16 -07002504 result = win32_lstat(path->wide, &st);
2505#else
2506 else
2507#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002508 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2509 result = LSTAT(path->narrow, &st);
2510 else
Steve Dowercc16be82016-09-08 10:35:16 -07002511#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002512#ifdef HAVE_FSTATAT
Ronald Oussoren41761932020-11-08 10:05:27 +01002513 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2514 if (HAVE_FSTATAT_RUNTIME) {
2515 result = fstatat(dir_fd, path->narrow, &st,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002516 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +01002517
2518 } else {
2519 fstatat_unavailable = 1;
2520 }
2521 } else
Steve Dowercc16be82016-09-08 10:35:16 -07002522#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002523 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002524#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002525 Py_END_ALLOW_THREADS
2526
Ronald Oussoren41761932020-11-08 10:05:27 +01002527#ifdef HAVE_FSTATAT
2528 if (fstatat_unavailable) {
2529 argument_unavailable_error("stat", "dir_fd");
2530 return NULL;
2531 }
2532#endif
2533
Victor Stinner292c8352012-10-30 02:17:38 +01002534 if (result != 0) {
2535 return path_error(path);
2536 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002537
Victor Stinner1c2fa782020-05-10 11:05:29 +02002538 return _pystat_fromstructstat(module, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002539}
2540
Larry Hastings2f936352014-08-05 14:04:04 +10002541/*[python input]
2542
2543for s in """
2544
2545FACCESSAT
2546FCHMODAT
2547FCHOWNAT
2548FSTATAT
2549LINKAT
2550MKDIRAT
2551MKFIFOAT
2552MKNODAT
2553OPENAT
2554READLINKAT
2555SYMLINKAT
2556UNLINKAT
2557
2558""".strip().split():
2559 s = s.strip()
2560 print("""
2561#ifdef HAVE_{s}
2562 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002563#else
Larry Hastings2f936352014-08-05 14:04:04 +10002564 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002565#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002566""".rstrip().format(s=s))
2567
2568for s in """
2569
2570FCHDIR
2571FCHMOD
2572FCHOWN
2573FDOPENDIR
2574FEXECVE
2575FPATHCONF
2576FSTATVFS
2577FTRUNCATE
2578
2579""".strip().split():
2580 s = s.strip()
2581 print("""
2582#ifdef HAVE_{s}
2583 #define PATH_HAVE_{s} 1
2584#else
2585 #define PATH_HAVE_{s} 0
2586#endif
2587
2588""".rstrip().format(s=s))
2589[python start generated code]*/
2590
2591#ifdef HAVE_FACCESSAT
2592 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2593#else
2594 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2595#endif
2596
2597#ifdef HAVE_FCHMODAT
2598 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2599#else
2600 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2601#endif
2602
2603#ifdef HAVE_FCHOWNAT
2604 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2605#else
2606 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2607#endif
2608
2609#ifdef HAVE_FSTATAT
2610 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2611#else
2612 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2613#endif
2614
2615#ifdef HAVE_LINKAT
2616 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2617#else
2618 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2619#endif
2620
2621#ifdef HAVE_MKDIRAT
2622 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2623#else
2624 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2625#endif
2626
2627#ifdef HAVE_MKFIFOAT
2628 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2629#else
2630 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2631#endif
2632
2633#ifdef HAVE_MKNODAT
2634 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2635#else
2636 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2637#endif
2638
2639#ifdef HAVE_OPENAT
2640 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2641#else
2642 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2643#endif
2644
2645#ifdef HAVE_READLINKAT
2646 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2647#else
2648 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2649#endif
2650
2651#ifdef HAVE_SYMLINKAT
2652 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2653#else
2654 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2655#endif
2656
2657#ifdef HAVE_UNLINKAT
2658 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2659#else
2660 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2661#endif
2662
2663#ifdef HAVE_FCHDIR
2664 #define PATH_HAVE_FCHDIR 1
2665#else
2666 #define PATH_HAVE_FCHDIR 0
2667#endif
2668
2669#ifdef HAVE_FCHMOD
2670 #define PATH_HAVE_FCHMOD 1
2671#else
2672 #define PATH_HAVE_FCHMOD 0
2673#endif
2674
2675#ifdef HAVE_FCHOWN
2676 #define PATH_HAVE_FCHOWN 1
2677#else
2678 #define PATH_HAVE_FCHOWN 0
2679#endif
2680
2681#ifdef HAVE_FDOPENDIR
2682 #define PATH_HAVE_FDOPENDIR 1
2683#else
2684 #define PATH_HAVE_FDOPENDIR 0
2685#endif
2686
2687#ifdef HAVE_FEXECVE
2688 #define PATH_HAVE_FEXECVE 1
2689#else
2690 #define PATH_HAVE_FEXECVE 0
2691#endif
2692
2693#ifdef HAVE_FPATHCONF
2694 #define PATH_HAVE_FPATHCONF 1
2695#else
2696 #define PATH_HAVE_FPATHCONF 0
2697#endif
2698
2699#ifdef HAVE_FSTATVFS
2700 #define PATH_HAVE_FSTATVFS 1
2701#else
2702 #define PATH_HAVE_FSTATVFS 0
2703#endif
2704
2705#ifdef HAVE_FTRUNCATE
2706 #define PATH_HAVE_FTRUNCATE 1
2707#else
2708 #define PATH_HAVE_FTRUNCATE 0
2709#endif
2710/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002711
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002712#ifdef MS_WINDOWS
2713 #undef PATH_HAVE_FTRUNCATE
2714 #define PATH_HAVE_FTRUNCATE 1
2715#endif
Larry Hastings31826802013-10-19 00:09:25 -07002716
Larry Hastings61272b72014-01-07 12:41:53 -08002717/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002718
2719class path_t_converter(CConverter):
2720
2721 type = "path_t"
2722 impl_by_reference = True
2723 parse_by_reference = True
2724
2725 converter = 'path_converter'
2726
2727 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002728 # right now path_t doesn't support default values.
2729 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002730 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002731 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002732
Larry Hastings2f936352014-08-05 14:04:04 +10002733 if self.c_default not in (None, 'Py_None'):
2734 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002735
2736 self.nullable = nullable
2737 self.allow_fd = allow_fd
2738
Larry Hastings7726ac92014-01-31 22:03:12 -08002739 def pre_render(self):
2740 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002741 if isinstance(value, str):
2742 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002743 return str(int(bool(value)))
2744
2745 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002746 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002747 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002748 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002749 strify(self.nullable),
2750 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002751 )
2752
2753 def cleanup(self):
2754 return "path_cleanup(&" + self.name + ");\n"
2755
2756
2757class dir_fd_converter(CConverter):
2758 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002759
Larry Hastings2f936352014-08-05 14:04:04 +10002760 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002761 if self.default in (unspecified, None):
2762 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002763 if isinstance(requires, str):
2764 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2765 else:
2766 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002767
Larry Hastings2f936352014-08-05 14:04:04 +10002768class uid_t_converter(CConverter):
2769 type = "uid_t"
2770 converter = '_Py_Uid_Converter'
2771
2772class gid_t_converter(CConverter):
2773 type = "gid_t"
2774 converter = '_Py_Gid_Converter'
2775
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002776class dev_t_converter(CConverter):
2777 type = 'dev_t'
2778 converter = '_Py_Dev_Converter'
2779
2780class dev_t_return_converter(unsigned_long_return_converter):
2781 type = 'dev_t'
2782 conversion_fn = '_PyLong_FromDev'
2783 unsigned_cast = '(dev_t)'
2784
Larry Hastings2f936352014-08-05 14:04:04 +10002785class FSConverter_converter(CConverter):
2786 type = 'PyObject *'
2787 converter = 'PyUnicode_FSConverter'
2788 def converter_init(self):
2789 if self.default is not unspecified:
2790 fail("FSConverter_converter does not support default values")
2791 self.c_default = 'NULL'
2792
2793 def cleanup(self):
2794 return "Py_XDECREF(" + self.name + ");\n"
2795
2796class pid_t_converter(CConverter):
2797 type = 'pid_t'
2798 format_unit = '" _Py_PARSE_PID "'
2799
2800class idtype_t_converter(int_converter):
2801 type = 'idtype_t'
2802
2803class id_t_converter(CConverter):
2804 type = 'id_t'
2805 format_unit = '" _Py_PARSE_PID "'
2806
Benjamin Petersonca470632016-09-06 13:47:26 -07002807class intptr_t_converter(CConverter):
2808 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002809 format_unit = '" _Py_PARSE_INTPTR "'
2810
2811class Py_off_t_converter(CConverter):
2812 type = 'Py_off_t'
2813 converter = 'Py_off_t_converter'
2814
2815class Py_off_t_return_converter(long_return_converter):
2816 type = 'Py_off_t'
2817 conversion_fn = 'PyLong_FromPy_off_t'
2818
2819class path_confname_converter(CConverter):
2820 type="int"
2821 converter="conv_path_confname"
2822
2823class confstr_confname_converter(path_confname_converter):
2824 converter='conv_confstr_confname'
2825
2826class sysconf_confname_converter(path_confname_converter):
2827 converter="conv_sysconf_confname"
2828
Larry Hastings61272b72014-01-07 12:41:53 -08002829[python start generated code]*/
Serhiy Storchaka9975cc52020-10-09 23:00:45 +03002830/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/
Larry Hastings31826802013-10-19 00:09:25 -07002831
Larry Hastings61272b72014-01-07 12:41:53 -08002832/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002833
Larry Hastings2a727912014-01-16 11:32:01 -08002834os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002835
2836 path : path_t(allow_fd=True)
BNMetricsb9427072018-11-02 15:20:19 +00002837 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002838 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002839
2840 *
2841
Larry Hastings2f936352014-08-05 14:04:04 +10002842 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002843 If not None, it should be a file descriptor open to a directory,
2844 and path should be a relative string; path will then be relative to
2845 that directory.
2846
2847 follow_symlinks: bool = True
2848 If False, and the last element of the path is a symbolic link,
2849 stat will examine the symbolic link itself instead of the file
2850 the link points to.
2851
2852Perform a stat system call on the given path.
2853
2854dir_fd and follow_symlinks may not be implemented
2855 on your platform. If they are unavailable, using them will raise a
2856 NotImplementedError.
2857
2858It's an error to use dir_fd or follow_symlinks when specifying path as
2859 an open file descriptor.
2860
Larry Hastings61272b72014-01-07 12:41:53 -08002861[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002862
Larry Hastings31826802013-10-19 00:09:25 -07002863static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002864os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002865/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002866{
Victor Stinner1c2fa782020-05-10 11:05:29 +02002867 return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks);
Larry Hastings31826802013-10-19 00:09:25 -07002868}
2869
Larry Hastings2f936352014-08-05 14:04:04 +10002870
2871/*[clinic input]
2872os.lstat
2873
2874 path : path_t
2875
2876 *
2877
2878 dir_fd : dir_fd(requires='fstatat') = None
2879
2880Perform a stat system call on the given path, without following symbolic links.
2881
2882Like stat(), but do not follow symbolic links.
2883Equivalent to stat(path, follow_symlinks=False).
2884[clinic start generated code]*/
2885
Larry Hastings2f936352014-08-05 14:04:04 +10002886static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002887os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2888/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002889{
2890 int follow_symlinks = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02002891 return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10002892}
Larry Hastings31826802013-10-19 00:09:25 -07002893
Larry Hastings2f936352014-08-05 14:04:04 +10002894
Larry Hastings61272b72014-01-07 12:41:53 -08002895/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002896os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002897
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002898 path: path_t
BNMetricsb9427072018-11-02 15:20:19 +00002899 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002900
2901 mode: int
2902 Operating-system mode bitfield. Can be F_OK to test existence,
2903 or the inclusive-OR of R_OK, W_OK, and X_OK.
2904
2905 *
2906
Larry Hastings2f936352014-08-05 14:04:04 +10002907 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002908 If not None, it should be a file descriptor open to a directory,
2909 and path should be relative; path will then be relative to that
2910 directory.
2911
2912 effective_ids: bool = False
2913 If True, access will use the effective uid/gid instead of
2914 the real uid/gid.
2915
2916 follow_symlinks: bool = True
2917 If False, and the last element of the path is a symbolic link,
2918 access will examine the symbolic link itself instead of the file
2919 the link points to.
2920
2921Use the real uid/gid to test for access to a path.
2922
2923{parameters}
2924dir_fd, effective_ids, and follow_symlinks may not be implemented
2925 on your platform. If they are unavailable, using them will raise a
2926 NotImplementedError.
2927
2928Note that most operations will use the effective uid/gid, therefore this
2929 routine can be used in a suid/sgid environment to test if the invoking user
2930 has the specified access to the path.
2931
Larry Hastings61272b72014-01-07 12:41:53 -08002932[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002933
Larry Hastings2f936352014-08-05 14:04:04 +10002934static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002935os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002936 int effective_ids, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00002937/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002938{
Larry Hastings2f936352014-08-05 14:04:04 +10002939 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002940
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002941#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002942 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002943#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002944 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002945#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002946
Ronald Oussoren41761932020-11-08 10:05:27 +01002947#ifdef HAVE_FACCESSAT
2948 int faccessat_unavailable = 0;
2949#endif
2950
Larry Hastings9cf065c2012-06-22 16:30:09 -07002951#ifndef HAVE_FACCESSAT
2952 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002953 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002954
2955 if (effective_ids) {
2956 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002957 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002958 }
2959#endif
2960
2961#ifdef MS_WINDOWS
2962 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002963 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002964 Py_END_ALLOW_THREADS
2965
2966 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002967 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002968 * * we didn't get a -1, and
2969 * * write access wasn't requested,
2970 * * or the file isn't read-only,
2971 * * or it's a directory.
2972 * (Directories cannot be read-only on Windows.)
2973 */
Larry Hastings2f936352014-08-05 14:04:04 +10002974 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002975 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002976 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002977 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002978#else
2979
2980 Py_BEGIN_ALLOW_THREADS
2981#ifdef HAVE_FACCESSAT
2982 if ((dir_fd != DEFAULT_DIR_FD) ||
2983 effective_ids ||
2984 !follow_symlinks) {
Ronald Oussoren41761932020-11-08 10:05:27 +01002985
2986 if (HAVE_FACCESSAT_RUNTIME) {
2987 int flags = 0;
2988 if (!follow_symlinks)
2989 flags |= AT_SYMLINK_NOFOLLOW;
2990 if (effective_ids)
2991 flags |= AT_EACCESS;
2992 result = faccessat(dir_fd, path->narrow, mode, flags);
2993 } else {
2994 faccessat_unavailable = 1;
2995 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002996 }
2997 else
2998#endif
Larry Hastings31826802013-10-19 00:09:25 -07002999 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003000 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01003001
3002#ifdef HAVE_FACCESSAT
3003 if (faccessat_unavailable) {
3004 if (dir_fd != DEFAULT_DIR_FD) {
3005 argument_unavailable_error("access", "dir_fd");
3006 return -1;
3007 }
3008 if (follow_symlinks_specified("access", follow_symlinks))
3009 return -1;
3010
3011 if (effective_ids) {
3012 argument_unavailable_error("access", "effective_ids");
3013 return -1;
3014 }
3015 /* should be unreachable */
3016 return -1;
3017 }
3018#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003019 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003020#endif
3021
Larry Hastings9cf065c2012-06-22 16:30:09 -07003022 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003023}
3024
Guido van Rossumd371ff11999-01-25 16:12:23 +00003025#ifndef F_OK
3026#define F_OK 0
3027#endif
3028#ifndef R_OK
3029#define R_OK 4
3030#endif
3031#ifndef W_OK
3032#define W_OK 2
3033#endif
3034#ifndef X_OK
3035#define X_OK 1
3036#endif
3037
Larry Hastings31826802013-10-19 00:09:25 -07003038
Guido van Rossumd371ff11999-01-25 16:12:23 +00003039#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08003040/*[clinic input]
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003041os.ttyname
Larry Hastings31826802013-10-19 00:09:25 -07003042
3043 fd: int
3044 Integer file descriptor handle.
3045
3046 /
3047
3048Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08003049[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07003050
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003051static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003052os_ttyname_impl(PyObject *module, int fd)
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003053/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
Larry Hastings31826802013-10-19 00:09:25 -07003054{
Guido van Rossum94f6f721999-01-06 18:42:14 +00003055
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02003056 long size = sysconf(_SC_TTY_NAME_MAX);
3057 if (size == -1) {
Serhiy Storchaka4db62e12018-12-17 16:47:45 +02003058 return posix_error();
3059 }
Antonio Gutierrez594e2ed2019-10-09 04:19:48 +02003060 char *buffer = (char *)PyMem_RawMalloc(size);
3061 if (buffer == NULL) {
3062 return PyErr_NoMemory();
3063 }
3064 int ret = ttyname_r(fd, buffer, size);
3065 if (ret != 0) {
3066 PyMem_RawFree(buffer);
3067 errno = ret;
3068 return posix_error();
3069 }
3070 PyObject *res = PyUnicode_DecodeFSDefault(buffer);
3071 PyMem_RawFree(buffer);
3072 return res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003073}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003074#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003075
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003076#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10003077/*[clinic input]
3078os.ctermid
3079
3080Return the name of the controlling terminal for this process.
3081[clinic start generated code]*/
3082
Larry Hastings2f936352014-08-05 14:04:04 +10003083static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003084os_ctermid_impl(PyObject *module)
3085/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003086{
Victor Stinner8c62be82010-05-06 00:08:46 +00003087 char *ret;
3088 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003089
Greg Wardb48bc172000-03-01 21:51:56 +00003090#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00003091 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003092#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003093 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003094#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003095 if (ret == NULL)
3096 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00003097 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003098}
Larry Hastings2f936352014-08-05 14:04:04 +10003099#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003100
Larry Hastings2f936352014-08-05 14:04:04 +10003101
3102/*[clinic input]
3103os.chdir
3104
3105 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
3106
3107Change the current working directory to the specified path.
3108
3109path may always be specified as a string.
3110On some platforms, path may also be specified as an open file descriptor.
3111 If this functionality is unavailable, using it raises an exception.
3112[clinic start generated code]*/
3113
Larry Hastings2f936352014-08-05 14:04:04 +10003114static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003115os_chdir_impl(PyObject *module, path_t *path)
3116/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003117{
3118 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003119
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003120 if (PySys_Audit("os.chdir", "(O)", path->object) < 0) {
3121 return NULL;
3122 }
3123
Larry Hastings9cf065c2012-06-22 16:30:09 -07003124 Py_BEGIN_ALLOW_THREADS
3125#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003126 /* on unix, success = 0, on windows, success = !0 */
3127 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003128#else
3129#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10003130 if (path->fd != -1)
3131 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003132 else
3133#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003134 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003135#endif
3136 Py_END_ALLOW_THREADS
3137
3138 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003139 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003140 }
3141
Larry Hastings2f936352014-08-05 14:04:04 +10003142 Py_RETURN_NONE;
3143}
3144
3145
3146#ifdef HAVE_FCHDIR
3147/*[clinic input]
3148os.fchdir
3149
3150 fd: fildes
3151
3152Change to the directory of the given file descriptor.
3153
3154fd must be opened on a directory, not a file.
3155Equivalent to os.chdir(fd).
3156
3157[clinic start generated code]*/
3158
Fred Drake4d1e64b2002-04-15 19:40:07 +00003159static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003160os_fchdir_impl(PyObject *module, int fd)
3161/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00003162{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003163 if (PySys_Audit("os.chdir", "(i)", fd) < 0) {
3164 return NULL;
3165 }
Larry Hastings2f936352014-08-05 14:04:04 +10003166 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00003167}
3168#endif /* HAVE_FCHDIR */
3169
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003170
Larry Hastings2f936352014-08-05 14:04:04 +10003171/*[clinic input]
3172os.chmod
3173
3174 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetricsb9427072018-11-02 15:20:19 +00003175 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10003176 On some platforms, path may also be specified as an open file descriptor.
3177 If this functionality is unavailable, using it raises an exception.
3178
3179 mode: int
3180 Operating-system mode bitfield.
3181
3182 *
3183
3184 dir_fd : dir_fd(requires='fchmodat') = None
3185 If not None, it should be a file descriptor open to a directory,
3186 and path should be relative; path will then be relative to that
3187 directory.
3188
3189 follow_symlinks: bool = True
3190 If False, and the last element of the path is a symbolic link,
3191 chmod will modify the symbolic link itself instead of the file
3192 the link points to.
3193
3194Change the access permissions of a file.
3195
3196It is an error to use dir_fd or follow_symlinks when specifying path as
3197 an open file descriptor.
3198dir_fd and follow_symlinks may not be implemented on your platform.
3199 If they are unavailable, using them will raise a NotImplementedError.
3200
3201[clinic start generated code]*/
3202
Larry Hastings2f936352014-08-05 14:04:04 +10003203static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003204os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003205 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003206/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003207{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003208 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003209
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003210#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003211 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003212#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003213
Larry Hastings9cf065c2012-06-22 16:30:09 -07003214#ifdef HAVE_FCHMODAT
3215 int fchmodat_nofollow_unsupported = 0;
Ronald Oussoren41761932020-11-08 10:05:27 +01003216 int fchmodat_unsupported = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003217#endif
3218
Larry Hastings9cf065c2012-06-22 16:30:09 -07003219#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
3220 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003221 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003222#endif
3223
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003224 if (PySys_Audit("os.chmod", "Oii", path->object, mode,
3225 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3226 return NULL;
3227 }
3228
Larry Hastings9cf065c2012-06-22 16:30:09 -07003229#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003230 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003231 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01003232 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003233 result = 0;
3234 else {
3235 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 attr &= ~FILE_ATTRIBUTE_READONLY;
3237 else
3238 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07003239 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003240 }
3241 Py_END_ALLOW_THREADS
3242
3243 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10003244 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003245 }
3246#else /* MS_WINDOWS */
3247 Py_BEGIN_ALLOW_THREADS
3248#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003249 if (path->fd != -1)
3250 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003251 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003252#endif /* HAVE_CHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003253#ifdef HAVE_LCHMOD
3254 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003255 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003257#endif /* HAVE_LCHMOD */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003258#ifdef HAVE_FCHMODAT
3259 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
Ronald Oussoren41761932020-11-08 10:05:27 +01003260 if (HAVE_FCHMODAT_RUNTIME) {
3261 /*
3262 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
3263 * The documentation specifically shows how to use it,
3264 * and then says it isn't implemented yet.
3265 * (true on linux with glibc 2.15, and openindiana 3.x)
3266 *
3267 * Once it is supported, os.chmod will automatically
3268 * support dir_fd and follow_symlinks=False. (Hopefully.)
3269 * Until then, we need to be careful what exception we raise.
3270 */
3271 result = fchmodat(dir_fd, path->narrow, mode,
3272 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3273 /*
3274 * But wait! We can't throw the exception without allowing threads,
3275 * and we can't do that in this nested scope. (Macro trickery, sigh.)
3276 */
3277 fchmodat_nofollow_unsupported =
3278 result &&
3279 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
3280 !follow_symlinks;
3281 } else {
3282 fchmodat_unsupported = 1;
3283 fchmodat_nofollow_unsupported = 1;
3284
3285 result = -1;
3286 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 }
3288 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003289#endif /* HAVE_FHCMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003290 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003291 Py_END_ALLOW_THREADS
3292
3293 if (result) {
3294#ifdef HAVE_FCHMODAT
Ronald Oussoren41761932020-11-08 10:05:27 +01003295 if (fchmodat_unsupported) {
3296 if (dir_fd != DEFAULT_DIR_FD) {
3297 argument_unavailable_error("chmod", "dir_fd");
3298 return NULL;
3299 }
3300 }
3301
Larry Hastings9cf065c2012-06-22 16:30:09 -07003302 if (fchmodat_nofollow_unsupported) {
3303 if (dir_fd != DEFAULT_DIR_FD)
3304 dir_fd_and_follow_symlinks_invalid("chmod",
3305 dir_fd, follow_symlinks);
3306 else
3307 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08003308 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003309 }
3310 else
Ronald Oussoren41761932020-11-08 10:05:27 +01003311#endif /* HAVE_FCHMODAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003312 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003313 }
Ronald Oussoren41761932020-11-08 10:05:27 +01003314#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003315
Larry Hastings2f936352014-08-05 14:04:04 +10003316 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003317}
3318
Larry Hastings9cf065c2012-06-22 16:30:09 -07003319
Christian Heimes4e30a842007-11-30 22:12:06 +00003320#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003321/*[clinic input]
3322os.fchmod
3323
3324 fd: int
3325 mode: int
3326
3327Change the access permissions of the file given by file descriptor fd.
3328
3329Equivalent to os.chmod(fd, mode).
3330[clinic start generated code]*/
3331
Larry Hastings2f936352014-08-05 14:04:04 +10003332static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003333os_fchmod_impl(PyObject *module, int fd, int mode)
3334/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003335{
3336 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003337 int async_err = 0;
3338
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003339 if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) {
3340 return NULL;
3341 }
3342
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003343 do {
3344 Py_BEGIN_ALLOW_THREADS
3345 res = fchmod(fd, mode);
3346 Py_END_ALLOW_THREADS
3347 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3348 if (res != 0)
3349 return (!async_err) ? posix_error() : NULL;
3350
Victor Stinner8c62be82010-05-06 00:08:46 +00003351 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003352}
3353#endif /* HAVE_FCHMOD */
3354
Larry Hastings2f936352014-08-05 14:04:04 +10003355
Christian Heimes4e30a842007-11-30 22:12:06 +00003356#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10003357/*[clinic input]
3358os.lchmod
3359
3360 path: path_t
3361 mode: int
3362
3363Change the access permissions of a file, without following symbolic links.
3364
3365If path is a symlink, this affects the link itself rather than the target.
3366Equivalent to chmod(path, mode, follow_symlinks=False)."
3367[clinic start generated code]*/
3368
Larry Hastings2f936352014-08-05 14:04:04 +10003369static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003370os_lchmod_impl(PyObject *module, path_t *path, int mode)
3371/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003372{
Victor Stinner8c62be82010-05-06 00:08:46 +00003373 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003374 if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) {
3375 return NULL;
3376 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003377 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003378 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003379 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003380 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003381 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003382 return NULL;
3383 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003384 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003385}
3386#endif /* HAVE_LCHMOD */
3387
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003388
Thomas Wouterscf297e42007-02-23 15:07:44 +00003389#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003390/*[clinic input]
3391os.chflags
3392
3393 path: path_t
3394 flags: unsigned_long(bitwise=True)
3395 follow_symlinks: bool=True
3396
3397Set file flags.
3398
3399If follow_symlinks is False, and the last element of the path is a symbolic
3400 link, chflags will change flags on the symbolic link itself instead of the
3401 file the link points to.
3402follow_symlinks may not be implemented on your platform. If it is
3403unavailable, using it will raise a NotImplementedError.
3404
3405[clinic start generated code]*/
3406
Larry Hastings2f936352014-08-05 14:04:04 +10003407static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003408os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003409 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003410/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003411{
3412 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413
3414#ifndef HAVE_LCHFLAGS
3415 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003416 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417#endif
3418
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003419 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3420 return NULL;
3421 }
3422
Victor Stinner8c62be82010-05-06 00:08:46 +00003423 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003424#ifdef HAVE_LCHFLAGS
3425 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003426 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427 else
3428#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003429 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431
Larry Hastings2f936352014-08-05 14:04:04 +10003432 if (result)
3433 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434
Larry Hastings2f936352014-08-05 14:04:04 +10003435 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003436}
3437#endif /* HAVE_CHFLAGS */
3438
Larry Hastings2f936352014-08-05 14:04:04 +10003439
Thomas Wouterscf297e42007-02-23 15:07:44 +00003440#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003441/*[clinic input]
3442os.lchflags
3443
3444 path: path_t
3445 flags: unsigned_long(bitwise=True)
3446
3447Set file flags.
3448
3449This function will not follow symbolic links.
3450Equivalent to chflags(path, flags, follow_symlinks=False).
3451[clinic start generated code]*/
3452
Larry Hastings2f936352014-08-05 14:04:04 +10003453static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003454os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3455/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003456{
Victor Stinner8c62be82010-05-06 00:08:46 +00003457 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003458 if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) {
3459 return NULL;
3460 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003461 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003462 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003464 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003465 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003466 }
Victor Stinner292c8352012-10-30 02:17:38 +01003467 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003468}
3469#endif /* HAVE_LCHFLAGS */
3470
Larry Hastings2f936352014-08-05 14:04:04 +10003471
Martin v. Löwis244edc82001-10-04 22:44:26 +00003472#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003473/*[clinic input]
3474os.chroot
3475 path: path_t
3476
3477Change root directory to path.
3478
3479[clinic start generated code]*/
3480
Larry Hastings2f936352014-08-05 14:04:04 +10003481static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003482os_chroot_impl(PyObject *module, path_t *path)
3483/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003484{
3485 int res;
3486 Py_BEGIN_ALLOW_THREADS
3487 res = chroot(path->narrow);
3488 Py_END_ALLOW_THREADS
3489 if (res < 0)
3490 return path_error(path);
3491 Py_RETURN_NONE;
3492}
3493#endif /* HAVE_CHROOT */
3494
Martin v. Löwis244edc82001-10-04 22:44:26 +00003495
Guido van Rossum21142a01999-01-08 21:05:37 +00003496#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003497/*[clinic input]
3498os.fsync
3499
3500 fd: fildes
3501
3502Force write of fd to disk.
3503[clinic start generated code]*/
3504
Larry Hastings2f936352014-08-05 14:04:04 +10003505static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003506os_fsync_impl(PyObject *module, int fd)
3507/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003508{
3509 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003510}
3511#endif /* HAVE_FSYNC */
3512
Larry Hastings2f936352014-08-05 14:04:04 +10003513
Ross Lagerwall7807c352011-03-17 20:20:30 +02003514#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003515/*[clinic input]
3516os.sync
3517
3518Force write of everything to disk.
3519[clinic start generated code]*/
3520
Larry Hastings2f936352014-08-05 14:04:04 +10003521static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003522os_sync_impl(PyObject *module)
3523/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003524{
3525 Py_BEGIN_ALLOW_THREADS
3526 sync();
3527 Py_END_ALLOW_THREADS
3528 Py_RETURN_NONE;
3529}
Larry Hastings2f936352014-08-05 14:04:04 +10003530#endif /* HAVE_SYNC */
3531
Ross Lagerwall7807c352011-03-17 20:20:30 +02003532
Guido van Rossum21142a01999-01-08 21:05:37 +00003533#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003534#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003535extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3536#endif
3537
Larry Hastings2f936352014-08-05 14:04:04 +10003538/*[clinic input]
3539os.fdatasync
3540
3541 fd: fildes
3542
3543Force write of fd to disk without forcing update of metadata.
3544[clinic start generated code]*/
3545
Larry Hastings2f936352014-08-05 14:04:04 +10003546static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003547os_fdatasync_impl(PyObject *module, int fd)
3548/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003549{
3550 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003551}
3552#endif /* HAVE_FDATASYNC */
3553
3554
Fredrik Lundh10723342000-07-10 16:38:09 +00003555#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003556/*[clinic input]
3557os.chown
3558
3559 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetricsb9427072018-11-02 15:20:19 +00003560 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003561
3562 uid: uid_t
3563
3564 gid: gid_t
3565
3566 *
3567
3568 dir_fd : dir_fd(requires='fchownat') = None
3569 If not None, it should be a file descriptor open to a directory,
3570 and path should be relative; path will then be relative to that
3571 directory.
3572
3573 follow_symlinks: bool = True
3574 If False, and the last element of the path is a symbolic link,
3575 stat will examine the symbolic link itself instead of the file
3576 the link points to.
3577
3578Change the owner and group id of path to the numeric uid and gid.\
3579
3580path may always be specified as a string.
3581On some platforms, path may also be specified as an open file descriptor.
3582 If this functionality is unavailable, using it raises an exception.
3583If dir_fd is not None, it should be a file descriptor open to a directory,
3584 and path should be relative; path will then be relative to that directory.
3585If follow_symlinks is False, and the last element of the path is a symbolic
3586 link, chown will modify the symbolic link itself instead of the file the
3587 link points to.
3588It is an error to use dir_fd or follow_symlinks when specifying path as
3589 an open file descriptor.
3590dir_fd and follow_symlinks may not be implemented on your platform.
3591 If they are unavailable, using them will raise a NotImplementedError.
3592
3593[clinic start generated code]*/
3594
Larry Hastings2f936352014-08-05 14:04:04 +10003595static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003596os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003597 int dir_fd, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +00003598/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003599{
3600 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601
Ronald Oussoren41761932020-11-08 10:05:27 +01003602#if defined(HAVE_FCHOWNAT)
3603 int fchownat_unsupported = 0;
3604#endif
3605
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3607 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003608 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003610 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3611 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3612 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003614 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid,
3615 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
3616 return NULL;
3617 }
3618
Victor Stinner8c62be82010-05-06 00:08:46 +00003619 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003620#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003621 if (path->fd != -1)
3622 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 else
3624#endif
3625#ifdef HAVE_LCHOWN
3626 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003627 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628 else
3629#endif
3630#ifdef HAVE_FCHOWNAT
Ronald Oussoren41761932020-11-08 10:05:27 +01003631 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
3632 if (HAVE_FCHOWNAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10003633 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +01003635 } else {
3636 fchownat_unsupported = 1;
3637 }
3638 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003639#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003640 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003641 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642
Ronald Oussoren41761932020-11-08 10:05:27 +01003643#ifdef HAVE_FCHOWNAT
3644 if (fchownat_unsupported) {
3645 /* This would be incorrect if the current platform
3646 * doesn't support lchown.
3647 */
3648 argument_unavailable_error(NULL, "dir_fd");
3649 return NULL;
3650 }
3651#endif
3652
Larry Hastings2f936352014-08-05 14:04:04 +10003653 if (result)
3654 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003655
Larry Hastings2f936352014-08-05 14:04:04 +10003656 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003657}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003658#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003659
Larry Hastings2f936352014-08-05 14:04:04 +10003660
Christian Heimes4e30a842007-11-30 22:12:06 +00003661#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003662/*[clinic input]
3663os.fchown
3664
3665 fd: int
3666 uid: uid_t
3667 gid: gid_t
3668
3669Change the owner and group id of the file specified by file descriptor.
3670
3671Equivalent to os.chown(fd, uid, gid).
3672
3673[clinic start generated code]*/
3674
Larry Hastings2f936352014-08-05 14:04:04 +10003675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003676os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3677/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003678{
Victor Stinner8c62be82010-05-06 00:08:46 +00003679 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003680 int async_err = 0;
3681
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003682 if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) {
3683 return NULL;
3684 }
3685
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003686 do {
3687 Py_BEGIN_ALLOW_THREADS
3688 res = fchown(fd, uid, gid);
3689 Py_END_ALLOW_THREADS
3690 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3691 if (res != 0)
3692 return (!async_err) ? posix_error() : NULL;
3693
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003695}
3696#endif /* HAVE_FCHOWN */
3697
Larry Hastings2f936352014-08-05 14:04:04 +10003698
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003699#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003700/*[clinic input]
3701os.lchown
3702
3703 path : path_t
3704 uid: uid_t
3705 gid: gid_t
3706
3707Change the owner and group id of path to the numeric uid and gid.
3708
3709This function will not follow symbolic links.
3710Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3711[clinic start generated code]*/
3712
Larry Hastings2f936352014-08-05 14:04:04 +10003713static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003714os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3715/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003716{
Victor Stinner8c62be82010-05-06 00:08:46 +00003717 int res;
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003718 if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) {
3719 return NULL;
3720 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003721 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003722 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003723 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003724 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003725 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003726 }
Larry Hastings2f936352014-08-05 14:04:04 +10003727 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003728}
3729#endif /* HAVE_LCHOWN */
3730
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003731
Barry Warsaw53699e91996-12-10 23:23:01 +00003732static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003733posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003734{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003735#ifdef MS_WINDOWS
Victor Stinner689830e2019-06-26 17:31:12 +02003736 wchar_t wbuf[MAXPATHLEN];
3737 wchar_t *wbuf2 = wbuf;
3738 DWORD len;
3739
3740 Py_BEGIN_ALLOW_THREADS
3741 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
3742 /* If the buffer is large enough, len does not include the
3743 terminating \0. If the buffer is too small, len includes
3744 the space needed for the terminator. */
3745 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerec3e20a2019-06-28 18:01:59 +02003746 if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003747 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003748 }
Victor Stinner689830e2019-06-26 17:31:12 +02003749 else {
3750 wbuf2 = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003751 }
Victor Stinner689830e2019-06-26 17:31:12 +02003752 if (wbuf2) {
3753 len = GetCurrentDirectoryW(len, wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003754 }
Victor Stinner689830e2019-06-26 17:31:12 +02003755 }
3756 Py_END_ALLOW_THREADS
3757
3758 if (!wbuf2) {
3759 PyErr_NoMemory();
3760 return NULL;
3761 }
3762 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003763 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003764 PyMem_RawFree(wbuf2);
Victor Stinner689830e2019-06-26 17:31:12 +02003765 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003766 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003767
Victor Stinner689830e2019-06-26 17:31:12 +02003768 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
3769 if (wbuf2 != wbuf) {
3770 PyMem_RawFree(wbuf2);
3771 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003772
Victor Stinner689830e2019-06-26 17:31:12 +02003773 if (use_bytes) {
3774 if (resobj == NULL) {
3775 return NULL;
3776 }
3777 Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj));
3778 }
3779
3780 return resobj;
3781#else
3782 const size_t chunk = 1024;
3783
3784 char *buf = NULL;
3785 char *cwd = NULL;
3786 size_t buflen = 0;
3787
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003789 do {
Victor Stinner689830e2019-06-26 17:31:12 +02003790 char *newbuf;
3791 if (buflen <= PY_SSIZE_T_MAX - chunk) {
3792 buflen += chunk;
3793 newbuf = PyMem_RawRealloc(buf, buflen);
3794 }
3795 else {
3796 newbuf = NULL;
3797 }
3798 if (newbuf == NULL) {
3799 PyMem_RawFree(buf);
3800 buf = NULL;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003801 break;
3802 }
Victor Stinner689830e2019-06-26 17:31:12 +02003803 buf = newbuf;
Victor Stinner4403d7d2015-04-25 00:16:10 +02003804
Victor Stinner4403d7d2015-04-25 00:16:10 +02003805 cwd = getcwd(buf, buflen);
3806 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003807 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003808
Victor Stinner689830e2019-06-26 17:31:12 +02003809 if (buf == NULL) {
3810 return PyErr_NoMemory();
3811 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003812 if (cwd == NULL) {
3813 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003814 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003815 }
3816
Victor Stinner689830e2019-06-26 17:31:12 +02003817 PyObject *obj;
3818 if (use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003819 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner689830e2019-06-26 17:31:12 +02003820 }
3821 else {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003822 obj = PyUnicode_DecodeFSDefault(buf);
Victor Stinner689830e2019-06-26 17:31:12 +02003823 }
Victor Stinner4403d7d2015-04-25 00:16:10 +02003824 PyMem_RawFree(buf);
3825
3826 return obj;
Victor Stinner689830e2019-06-26 17:31:12 +02003827#endif /* !MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003828}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003829
Larry Hastings2f936352014-08-05 14:04:04 +10003830
3831/*[clinic input]
3832os.getcwd
3833
3834Return a unicode string representing the current working directory.
3835[clinic start generated code]*/
3836
Larry Hastings2f936352014-08-05 14:04:04 +10003837static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003838os_getcwd_impl(PyObject *module)
3839/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003840{
3841 return posix_getcwd(0);
3842}
3843
Larry Hastings2f936352014-08-05 14:04:04 +10003844
3845/*[clinic input]
3846os.getcwdb
3847
3848Return a bytes string representing the current working directory.
3849[clinic start generated code]*/
3850
Larry Hastings2f936352014-08-05 14:04:04 +10003851static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003852os_getcwdb_impl(PyObject *module)
3853/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003854{
3855 return posix_getcwd(1);
3856}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003857
Larry Hastings2f936352014-08-05 14:04:04 +10003858
Larry Hastings9cf065c2012-06-22 16:30:09 -07003859#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3860#define HAVE_LINK 1
3861#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003862
Guido van Rossumb6775db1994-08-01 11:34:53 +00003863#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003864/*[clinic input]
3865
3866os.link
3867
3868 src : path_t
3869 dst : path_t
3870 *
3871 src_dir_fd : dir_fd = None
3872 dst_dir_fd : dir_fd = None
3873 follow_symlinks: bool = True
3874
3875Create a hard link to a file.
3876
3877If either src_dir_fd or dst_dir_fd is not None, it should be a file
3878 descriptor open to a directory, and the respective path string (src or dst)
3879 should be relative; the path will then be relative to that directory.
3880If follow_symlinks is False, and the last element of src is a symbolic
3881 link, link will create a link to the symbolic link itself instead of the
3882 file the link points to.
3883src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3884 platform. If they are unavailable, using them will raise a
3885 NotImplementedError.
3886[clinic start generated code]*/
3887
Larry Hastings2f936352014-08-05 14:04:04 +10003888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003889os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003890 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003891/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003892{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003893#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003894 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003895#else
3896 int result;
3897#endif
Ronald Oussoren41761932020-11-08 10:05:27 +01003898#if defined(HAVE_LINKAT)
3899 int linkat_unavailable = 0;
3900#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003901
Larry Hastings9cf065c2012-06-22 16:30:09 -07003902#ifndef HAVE_LINKAT
3903 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3904 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003905 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003906 }
3907#endif
3908
Steve Dowercc16be82016-09-08 10:35:16 -07003909#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003910 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003911 PyErr_SetString(PyExc_NotImplementedError,
3912 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003913 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003914 }
Steve Dowercc16be82016-09-08 10:35:16 -07003915#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003916
Saiyang Gou7514f4f2020-02-12 23:47:42 -08003917 if (PySys_Audit("os.link", "OOii", src->object, dst->object,
3918 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
3919 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
3920 return NULL;
3921 }
3922
Brian Curtin1b9df392010-11-24 20:24:31 +00003923#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003924 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003925 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003926 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003927
Larry Hastings2f936352014-08-05 14:04:04 +10003928 if (!result)
3929 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003930#else
3931 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003932#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003933 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3934 (dst_dir_fd != DEFAULT_DIR_FD) ||
Ronald Oussoren41761932020-11-08 10:05:27 +01003935 (!follow_symlinks)) {
3936
3937 if (HAVE_LINKAT_RUNTIME) {
3938
3939 result = linkat(src_dir_fd, src->narrow,
3940 dst_dir_fd, dst->narrow,
3941 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3942
3943 }
3944#ifdef __APPLE__
3945 else {
3946 if (src_dir_fd == DEFAULT_DIR_FD && dst_dir_fd == DEFAULT_DIR_FD) {
3947 /* See issue 41355: This matches the behaviour of !HAVE_LINKAT */
3948 result = link(src->narrow, dst->narrow);
3949 } else {
3950 linkat_unavailable = 1;
3951 }
3952 }
3953#endif
3954 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003955 else
Steve Dowercc16be82016-09-08 10:35:16 -07003956#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003957 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003958 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003959
Ronald Oussoren41761932020-11-08 10:05:27 +01003960#ifdef HAVE_LINKAT
3961 if (linkat_unavailable) {
3962 /* Either or both dir_fd arguments were specified */
3963 if (src_dir_fd != DEFAULT_DIR_FD) {
3964 argument_unavailable_error("link", "src_dir_fd");
3965 } else {
3966 argument_unavailable_error("link", "dst_dir_fd");
3967 }
3968 return NULL;
3969 }
3970#endif
3971
Larry Hastings2f936352014-08-05 14:04:04 +10003972 if (result)
3973 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003974#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003975
Larry Hastings2f936352014-08-05 14:04:04 +10003976 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003977}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003978#endif
3979
Brian Curtin1b9df392010-11-24 20:24:31 +00003980
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003981#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003982static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003983_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003984{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003985 PyObject *v;
3986 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3987 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003988 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003989 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003990 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003991 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003992
Steve Dowercc16be82016-09-08 10:35:16 -07003993 WIN32_FIND_DATAW wFileData;
3994 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003995
Steve Dowercc16be82016-09-08 10:35:16 -07003996 if (!path->wide) { /* Default arg: "." */
3997 po_wchars = L".";
3998 len = 1;
3999 } else {
4000 po_wchars = path->wide;
4001 len = wcslen(path->wide);
4002 }
4003 /* The +5 is so we can append "\\*.*\0" */
4004 wnamebuf = PyMem_New(wchar_t, len + 5);
4005 if (!wnamebuf) {
4006 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07004007 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004008 }
Steve Dowercc16be82016-09-08 10:35:16 -07004009 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00004010 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07004011 wchar_t wch = wnamebuf[len-1];
4012 if (wch != SEP && wch != ALTSEP && wch != L':')
4013 wnamebuf[len++] = SEP;
4014 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00004015 }
Steve Dowercc16be82016-09-08 10:35:16 -07004016 if ((list = PyList_New(0)) == NULL) {
4017 goto exit;
4018 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00004019 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004020 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00004021 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00004022 if (hFindFile == INVALID_HANDLE_VALUE) {
4023 int error = GetLastError();
4024 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004025 goto exit;
4026 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004027 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004028 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004029 }
4030 do {
4031 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07004032 if (wcscmp(wFileData.cFileName, L".") != 0 &&
4033 wcscmp(wFileData.cFileName, L"..") != 0) {
4034 v = PyUnicode_FromWideChar(wFileData.cFileName,
4035 wcslen(wFileData.cFileName));
4036 if (path->narrow && v) {
4037 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
4038 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004039 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004040 Py_DECREF(list);
4041 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004042 break;
4043 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004044 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004045 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004046 Py_DECREF(list);
4047 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004048 break;
4049 }
4050 Py_DECREF(v);
4051 }
4052 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004053 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00004054 Py_END_ALLOW_THREADS
4055 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
4056 it got to the end of the directory. */
4057 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004058 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004059 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004060 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004061 }
4062 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004063
Larry Hastings9cf065c2012-06-22 16:30:09 -07004064exit:
4065 if (hFindFile != INVALID_HANDLE_VALUE) {
4066 if (FindClose(hFindFile) == FALSE) {
4067 if (list != NULL) {
4068 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004069 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004070 }
4071 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004072 }
Victor Stinnerb6404912013-07-07 16:21:41 +02004073 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004074
Larry Hastings9cf065c2012-06-22 16:30:09 -07004075 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004076} /* end of _listdir_windows_no_opendir */
4077
4078#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
4079
4080static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07004081_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004082{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004083 PyObject *v;
4084 DIR *dirp = NULL;
4085 struct dirent *ep;
4086 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004087#ifdef HAVE_FDOPENDIR
4088 int fd = -1;
4089#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004090
Victor Stinner8c62be82010-05-06 00:08:46 +00004091 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004092#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07004093 if (path->fd != -1) {
Ronald Oussoren41761932020-11-08 10:05:27 +01004094 if (HAVE_FDOPENDIR_RUNTIME) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004095 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02004096 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01004097 if (fd == -1)
4098 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004099
Larry Hastingsfdaea062012-06-25 04:42:23 -07004100 return_str = 1;
4101
Larry Hastings9cf065c2012-06-22 16:30:09 -07004102 Py_BEGIN_ALLOW_THREADS
4103 dirp = fdopendir(fd);
4104 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01004105 } else {
4106 PyErr_SetString(PyExc_TypeError,
4107 "listdir: path should be string, bytes, os.PathLike or None, not int");
4108 return NULL;
4109 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004110 }
4111 else
4112#endif
4113 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004114 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07004115 if (path->narrow) {
4116 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03004117 /* only return bytes if they specified a bytes-like object */
4118 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07004119 }
4120 else {
4121 name = ".";
4122 return_str = 1;
4123 }
4124
Larry Hastings9cf065c2012-06-22 16:30:09 -07004125 Py_BEGIN_ALLOW_THREADS
4126 dirp = opendir(name);
4127 Py_END_ALLOW_THREADS
4128 }
4129
4130 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07004131 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004132#ifdef HAVE_FDOPENDIR
4133 if (fd != -1) {
4134 Py_BEGIN_ALLOW_THREADS
4135 close(fd);
4136 Py_END_ALLOW_THREADS
4137 }
4138#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004139 goto exit;
4140 }
4141 if ((list = PyList_New(0)) == NULL) {
4142 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004143 }
4144 for (;;) {
4145 errno = 0;
4146 Py_BEGIN_ALLOW_THREADS
4147 ep = readdir(dirp);
4148 Py_END_ALLOW_THREADS
4149 if (ep == NULL) {
4150 if (errno == 0) {
4151 break;
4152 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004153 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07004154 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004156 }
4157 }
4158 if (ep->d_name[0] == '.' &&
4159 (NAMLEN(ep) == 1 ||
4160 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
4161 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07004162 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00004163 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
4164 else
4165 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00004166 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004167 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004168 break;
4169 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004170 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004171 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004172 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00004173 break;
4174 }
4175 Py_DECREF(v);
4176 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00004177
Larry Hastings9cf065c2012-06-22 16:30:09 -07004178exit:
4179 if (dirp != NULL) {
4180 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004181#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07004182 if (fd > -1)
4183 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07004184#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004185 closedir(dirp);
4186 Py_END_ALLOW_THREADS
4187 }
4188
Larry Hastings9cf065c2012-06-22 16:30:09 -07004189 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07004190} /* end of _posix_listdir */
4191#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004192
Larry Hastings2f936352014-08-05 14:04:04 +10004193
4194/*[clinic input]
4195os.listdir
4196
4197 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
4198
4199Return a list containing the names of the files in the directory.
4200
BNMetricsb9427072018-11-02 15:20:19 +00004201path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10004202 the filenames returned will also be bytes; in all other circumstances
4203 the filenames returned will be str.
4204If path is None, uses the path='.'.
4205On some platforms, path may also be specified as an open file descriptor;\
4206 the file descriptor must refer to a directory.
4207 If this functionality is unavailable, using it raises NotImplementedError.
4208
4209The list is in arbitrary order. It does not include the special
4210entries '.' and '..' even if they are present in the directory.
4211
4212
4213[clinic start generated code]*/
4214
Larry Hastings2f936352014-08-05 14:04:04 +10004215static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004216os_listdir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +00004217/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004218{
Steve Dower60419a72019-06-24 08:42:54 -07004219 if (PySys_Audit("os.listdir", "O",
4220 path->object ? path->object : Py_None) < 0) {
4221 return NULL;
4222 }
Larry Hastings2f936352014-08-05 14:04:04 +10004223#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
4224 return _listdir_windows_no_opendir(path, NULL);
4225#else
4226 return _posix_listdir(path, NULL);
4227#endif
4228}
4229
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004230#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00004231/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004232/*[clinic input]
4233os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02004234
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004235 path: path_t
4236 /
4237
4238[clinic start generated code]*/
4239
4240static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004241os__getfullpathname_impl(PyObject *module, path_t *path)
4242/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03004243{
Victor Stinner3939c322019-06-25 15:02:43 +02004244 wchar_t *abspath;
Victor Stinnereb5657a2011-09-30 01:44:27 +02004245
Victor Stinner3939c322019-06-25 15:02:43 +02004246 /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */
4247 if (_Py_abspath(path->wide, &abspath) < 0) {
4248 return win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00004249 }
Victor Stinner3939c322019-06-25 15:02:43 +02004250 if (abspath == NULL) {
4251 return PyErr_NoMemory();
4252 }
4253
4254 PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
4255 PyMem_RawFree(abspath);
4256 if (str == NULL) {
4257 return NULL;
4258 }
4259 if (path->narrow) {
4260 Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
4261 }
4262 return str;
Larry Hastings2f936352014-08-05 14:04:04 +10004263}
Brian Curtind40e6f72010-07-08 21:39:08 +00004264
Brian Curtind25aef52011-06-13 15:16:04 -05004265
Larry Hastings2f936352014-08-05 14:04:04 +10004266/*[clinic input]
4267os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00004268
Steve Dower23ad6d02018-02-22 10:39:10 -08004269 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004270 /
4271
4272A helper function for samepath on windows.
4273[clinic start generated code]*/
4274
Larry Hastings2f936352014-08-05 14:04:04 +10004275static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004276os__getfinalpathname_impl(PyObject *module, path_t *path)
4277/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00004278{
4279 HANDLE hFile;
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004280 wchar_t buf[MAXPATHLEN], *target_path = buf;
4281 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00004282 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10004283 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004284
Steve Dower23ad6d02018-02-22 10:39:10 -08004285 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004286 hFile = CreateFileW(
Steve Dower23ad6d02018-02-22 10:39:10 -08004287 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00004288 0, /* desired access */
4289 0, /* share mode */
4290 NULL, /* security attributes */
4291 OPEN_EXISTING,
4292 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
4293 FILE_FLAG_BACKUP_SEMANTICS,
4294 NULL);
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004295 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004296
Steve Dower23ad6d02018-02-22 10:39:10 -08004297 if (hFile == INVALID_HANDLE_VALUE) {
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004298 return win32_error_object("CreateFileW", path->object);
Steve Dower23ad6d02018-02-22 10:39:10 -08004299 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004300
4301 /* We have a good handle to the target, use it to determine the
4302 target path name. */
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004303 while (1) {
4304 Py_BEGIN_ALLOW_THREADS
4305 result_length = GetFinalPathNameByHandleW(hFile, target_path,
4306 buf_size, VOLUME_NAME_DOS);
4307 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00004308
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004309 if (!result_length) {
4310 result = win32_error_object("GetFinalPathNameByHandleW",
4311 path->object);
4312 goto cleanup;
4313 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004314
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004315 if (result_length < buf_size) {
4316 break;
4317 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004318
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004319 wchar_t *tmp;
4320 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
4321 result_length * sizeof(*tmp));
4322 if (!tmp) {
4323 result = PyErr_NoMemory();
4324 goto cleanup;
4325 }
4326
4327 buf_size = result_length;
4328 target_path = tmp;
Steve Dower23ad6d02018-02-22 10:39:10 -08004329 }
Brian Curtind40e6f72010-07-08 21:39:08 +00004330
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004331 result = PyUnicode_FromWideChar(target_path, result_length);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004332 if (result && path->narrow) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004333 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Steve Dowerdf2d4a62019-08-21 15:27:33 -07004334 }
Steve Dower23ad6d02018-02-22 10:39:10 -08004335
Alexey Izbyshev3b20d342018-03-08 19:03:25 +03004336cleanup:
4337 if (target_path != buf) {
4338 PyMem_Free(target_path);
4339 }
4340 CloseHandle(hFile);
4341 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10004342}
Brian Curtin62857742010-09-06 17:07:27 +00004343
Tim Golden6b528062013-08-01 12:44:00 +01004344
Larry Hastings2f936352014-08-05 14:04:04 +10004345/*[clinic input]
4346os._getvolumepathname
4347
Steve Dower23ad6d02018-02-22 10:39:10 -08004348 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004349
4350A helper function for ismount on Win32.
4351[clinic start generated code]*/
4352
Larry Hastings2f936352014-08-05 14:04:04 +10004353static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -08004354os__getvolumepathname_impl(PyObject *module, path_t *path)
4355/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004356{
4357 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004358 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004359 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004360 BOOL ret;
4361
Tim Golden6b528062013-08-01 12:44:00 +01004362 /* Volume path should be shorter than entire path */
Steve Dower23ad6d02018-02-22 10:39:10 -08004363 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01004364
Victor Stinner850a18e2017-10-24 16:53:32 -07004365 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01004366 PyErr_SetString(PyExc_OverflowError, "path too long");
4367 return NULL;
4368 }
4369
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004370 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004371 if (mountpath == NULL)
4372 return PyErr_NoMemory();
4373
4374 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -08004375 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004376 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004377 Py_END_ALLOW_THREADS
4378
4379 if (!ret) {
Steve Dower23ad6d02018-02-22 10:39:10 -08004380 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01004381 goto exit;
4382 }
4383 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Steve Dower23ad6d02018-02-22 10:39:10 -08004384 if (path->narrow)
4385 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01004386
4387exit:
4388 PyMem_Free(mountpath);
4389 return result;
4390}
Tim Golden6b528062013-08-01 12:44:00 +01004391
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004392#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004393
Larry Hastings2f936352014-08-05 14:04:04 +10004394
4395/*[clinic input]
4396os.mkdir
4397
4398 path : path_t
4399
4400 mode: int = 0o777
4401
4402 *
4403
4404 dir_fd : dir_fd(requires='mkdirat') = None
4405
4406# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4407
4408Create a directory.
4409
4410If dir_fd is not None, it should be a file descriptor open to a directory,
4411 and path should be relative; path will then be relative to that directory.
4412dir_fd may not be implemented on your platform.
4413 If it is unavailable, using it will raise a NotImplementedError.
4414
4415The mode argument is ignored on Windows.
4416[clinic start generated code]*/
4417
Larry Hastings2f936352014-08-05 14:04:04 +10004418static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004419os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4420/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004421{
4422 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004423#ifdef HAVE_MKDIRAT
4424 int mkdirat_unavailable = 0;
4425#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004426
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004427 if (PySys_Audit("os.mkdir", "Oii", path->object, mode,
4428 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4429 return NULL;
4430 }
4431
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004432#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004433 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004434 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004435 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004436
Larry Hastings2f936352014-08-05 14:04:04 +10004437 if (!result)
4438 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004439#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004440 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004441#if HAVE_MKDIRAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004442 if (dir_fd != DEFAULT_DIR_FD) {
4443 if (HAVE_MKDIRAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004444 result = mkdirat(dir_fd, path->narrow, mode);
Ronald Oussoren41761932020-11-08 10:05:27 +01004445
4446 } else {
4447 mkdirat_unavailable = 1;
4448 }
4449 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02004451#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004452 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004453#else
Larry Hastings2f936352014-08-05 14:04:04 +10004454 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004455#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004456 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01004457
4458#if HAVE_MKDIRAT
4459 if (mkdirat_unavailable) {
4460 argument_unavailable_error(NULL, "dir_fd");
4461 return NULL;
4462 }
4463#endif
4464
Larry Hastings2f936352014-08-05 14:04:04 +10004465 if (result < 0)
4466 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07004467#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10004468 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004469}
4470
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004471
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004472/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4473#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004474#include <sys/resource.h>
4475#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004476
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004477
4478#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004479/*[clinic input]
4480os.nice
4481
4482 increment: int
4483 /
4484
4485Add increment to the priority of process and return the new priority.
4486[clinic start generated code]*/
4487
Larry Hastings2f936352014-08-05 14:04:04 +10004488static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004489os_nice_impl(PyObject *module, int increment)
4490/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004491{
4492 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004493
Victor Stinner8c62be82010-05-06 00:08:46 +00004494 /* There are two flavours of 'nice': one that returns the new
4495 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07004496 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00004497 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004498
Victor Stinner8c62be82010-05-06 00:08:46 +00004499 If we are of the nice family that returns the new priority, we
4500 need to clear errno before the call, and check if errno is filled
4501 before calling posix_error() on a returnvalue of -1, because the
4502 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004503
Victor Stinner8c62be82010-05-06 00:08:46 +00004504 errno = 0;
4505 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004506#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004507 if (value == 0)
4508 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004509#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004510 if (value == -1 && errno != 0)
4511 /* either nice() or getpriority() returned an error */
4512 return posix_error();
4513 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004514}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004515#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004516
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004517
4518#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004519/*[clinic input]
4520os.getpriority
4521
4522 which: int
4523 who: int
4524
4525Return program scheduling priority.
4526[clinic start generated code]*/
4527
Larry Hastings2f936352014-08-05 14:04:04 +10004528static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004529os_getpriority_impl(PyObject *module, int which, int who)
4530/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004531{
4532 int retval;
4533
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004534 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004535 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004536 if (errno != 0)
4537 return posix_error();
4538 return PyLong_FromLong((long)retval);
4539}
4540#endif /* HAVE_GETPRIORITY */
4541
4542
4543#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004544/*[clinic input]
4545os.setpriority
4546
4547 which: int
4548 who: int
4549 priority: int
4550
4551Set program scheduling priority.
4552[clinic start generated code]*/
4553
Larry Hastings2f936352014-08-05 14:04:04 +10004554static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004555os_setpriority_impl(PyObject *module, int which, int who, int priority)
4556/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004557{
4558 int retval;
4559
4560 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004561 if (retval == -1)
4562 return posix_error();
4563 Py_RETURN_NONE;
4564}
4565#endif /* HAVE_SETPRIORITY */
4566
4567
Barry Warsaw53699e91996-12-10 23:23:01 +00004568static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004569internal_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 +00004570{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004571 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004573
Ronald Oussoren41761932020-11-08 10:05:27 +01004574#ifdef HAVE_RENAMEAT
4575 int renameat_unavailable = 0;
4576#endif
4577
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004578#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004579 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004580 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004581#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004583#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4586 (dst_dir_fd != DEFAULT_DIR_FD);
4587#ifndef HAVE_RENAMEAT
4588 if (dir_fd_specified) {
4589 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004590 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591 }
4592#endif
4593
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004594 if (PySys_Audit("os.rename", "OOii", src->object, dst->object,
4595 src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd,
4596 dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) {
4597 return NULL;
4598 }
4599
Larry Hastings9cf065c2012-06-22 16:30:09 -07004600#ifdef MS_WINDOWS
4601 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004602 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004603 Py_END_ALLOW_THREADS
4604
Larry Hastings2f936352014-08-05 14:04:04 +10004605 if (!result)
4606 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004607
4608#else
Steve Dowercc16be82016-09-08 10:35:16 -07004609 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4610 PyErr_Format(PyExc_ValueError,
4611 "%s: src and dst must be the same type", function_name);
4612 return NULL;
4613 }
4614
Larry Hastings9cf065c2012-06-22 16:30:09 -07004615 Py_BEGIN_ALLOW_THREADS
4616#ifdef HAVE_RENAMEAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004617 if (dir_fd_specified) {
4618 if (HAVE_RENAMEAT_RUNTIME) {
4619 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
4620 } else {
4621 renameat_unavailable = 1;
4622 }
4623 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004624#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004625 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004626 Py_END_ALLOW_THREADS
4627
Ronald Oussoren41761932020-11-08 10:05:27 +01004628
4629#ifdef HAVE_RENAMEAT
4630 if (renameat_unavailable) {
4631 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4632 return NULL;
4633 }
4634#endif
4635
Larry Hastings2f936352014-08-05 14:04:04 +10004636 if (result)
4637 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004638#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004639 Py_RETURN_NONE;
4640}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641
Larry Hastings2f936352014-08-05 14:04:04 +10004642
4643/*[clinic input]
4644os.rename
4645
4646 src : path_t
4647 dst : path_t
4648 *
4649 src_dir_fd : dir_fd = None
4650 dst_dir_fd : dir_fd = None
4651
4652Rename a file or directory.
4653
4654If either src_dir_fd or dst_dir_fd is not None, it should be a file
4655 descriptor open to a directory, and the respective path string (src or dst)
4656 should be relative; the path will then be relative to that directory.
4657src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4658 If they are unavailable, using them will raise a NotImplementedError.
4659[clinic start generated code]*/
4660
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004661static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004662os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004663 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004664/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004665{
Larry Hastings2f936352014-08-05 14:04:04 +10004666 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004667}
4668
Larry Hastings2f936352014-08-05 14:04:04 +10004669
4670/*[clinic input]
4671os.replace = os.rename
4672
4673Rename a file or directory, overwriting the destination.
4674
4675If either src_dir_fd or dst_dir_fd is not None, it should be a file
4676 descriptor open to a directory, and the respective path string (src or dst)
4677 should be relative; the path will then be relative to that directory.
4678src_dir_fd and dst_dir_fd, may not be implemented on your platform.
Anthony Sottile73d60022019-02-12 23:15:54 -05004679 If they are unavailable, using them will raise a NotImplementedError.
Larry Hastings2f936352014-08-05 14:04:04 +10004680[clinic start generated code]*/
4681
Larry Hastings2f936352014-08-05 14:04:04 +10004682static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004683os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4684 int dst_dir_fd)
Anthony Sottile73d60022019-02-12 23:15:54 -05004685/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004686{
4687 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4688}
4689
4690
4691/*[clinic input]
4692os.rmdir
4693
4694 path: path_t
4695 *
4696 dir_fd: dir_fd(requires='unlinkat') = None
4697
4698Remove a directory.
4699
4700If dir_fd is not None, it should be a file descriptor open to a directory,
4701 and path should be relative; path will then be relative to that directory.
4702dir_fd may not be implemented on your platform.
4703 If it is unavailable, using it will raise a NotImplementedError.
4704[clinic start generated code]*/
4705
Larry Hastings2f936352014-08-05 14:04:04 +10004706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004707os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4708/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004709{
4710 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004711#ifdef HAVE_UNLINKAT
4712 int unlinkat_unavailable = 0;
4713#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004714
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004715 if (PySys_Audit("os.rmdir", "Oi", path->object,
4716 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4717 return NULL;
4718 }
4719
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004720 Py_BEGIN_ALLOW_THREADS
4721#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004722 /* Windows, success=1, UNIX, success=0 */
4723 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004724#else
4725#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004726 if (dir_fd != DEFAULT_DIR_FD) {
4727 if (HAVE_UNLINKAT_RUNTIME) {
Larry Hastings2f936352014-08-05 14:04:04 +10004728 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Ronald Oussoren41761932020-11-08 10:05:27 +01004729 } else {
4730 unlinkat_unavailable = 1;
4731 result = -1;
4732 }
4733 } else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004734#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004735 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004736#endif
4737 Py_END_ALLOW_THREADS
4738
Ronald Oussoren41761932020-11-08 10:05:27 +01004739#ifdef HAVE_UNLINKAT
4740 if (unlinkat_unavailable) {
4741 argument_unavailable_error("rmdir", "dir_fd");
4742 return NULL;
4743 }
4744#endif
4745
Larry Hastings2f936352014-08-05 14:04:04 +10004746 if (result)
4747 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004748
Larry Hastings2f936352014-08-05 14:04:04 +10004749 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004750}
4751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004752
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004753#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004754#ifdef MS_WINDOWS
4755/*[clinic input]
4756os.system -> long
4757
4758 command: Py_UNICODE
4759
4760Execute the command in a subshell.
4761[clinic start generated code]*/
4762
Larry Hastings2f936352014-08-05 14:04:04 +10004763static long
Serhiy Storchakaafb3e712018-12-14 11:19:51 +02004764os_system_impl(PyObject *module, const Py_UNICODE *command)
4765/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004766{
4767 long result;
Steve Dowerb82e17e2019-05-23 08:45:22 -07004768
Steve Dowerfbe3c762019-10-18 00:52:15 -07004769 if (PySys_Audit("os.system", "(u)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004770 return -1;
4771 }
4772
Victor Stinner8c62be82010-05-06 00:08:46 +00004773 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004774 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004775 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004776 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004777 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004778 return result;
4779}
4780#else /* MS_WINDOWS */
4781/*[clinic input]
4782os.system -> long
4783
4784 command: FSConverter
4785
4786Execute the command in a subshell.
4787[clinic start generated code]*/
4788
Larry Hastings2f936352014-08-05 14:04:04 +10004789static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004790os_system_impl(PyObject *module, PyObject *command)
4791/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004792{
4793 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004794 const char *bytes = PyBytes_AsString(command);
Steve Dowerb82e17e2019-05-23 08:45:22 -07004795
Steve Dowerfbe3c762019-10-18 00:52:15 -07004796 if (PySys_Audit("os.system", "(O)", command) < 0) {
Steve Dowerb82e17e2019-05-23 08:45:22 -07004797 return -1;
4798 }
4799
Larry Hastings2f936352014-08-05 14:04:04 +10004800 Py_BEGIN_ALLOW_THREADS
4801 result = system(bytes);
4802 Py_END_ALLOW_THREADS
4803 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004804}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004805#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004806#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004808
Larry Hastings2f936352014-08-05 14:04:04 +10004809/*[clinic input]
4810os.umask
4811
4812 mask: int
4813 /
4814
4815Set the current numeric umask and return the previous umask.
4816[clinic start generated code]*/
4817
Larry Hastings2f936352014-08-05 14:04:04 +10004818static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004819os_umask_impl(PyObject *module, int mask)
4820/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004821{
4822 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004823 if (i < 0)
4824 return posix_error();
4825 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004826}
4827
Brian Curtind40e6f72010-07-08 21:39:08 +00004828#ifdef MS_WINDOWS
4829
4830/* override the default DeleteFileW behavior so that directory
4831symlinks can be removed with this function, the same as with
4832Unix symlinks */
4833BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4834{
4835 WIN32_FILE_ATTRIBUTE_DATA info;
4836 WIN32_FIND_DATAW find_data;
4837 HANDLE find_data_handle;
4838 int is_directory = 0;
4839 int is_link = 0;
4840
4841 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4842 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004843
Brian Curtind40e6f72010-07-08 21:39:08 +00004844 /* Get WIN32_FIND_DATA structure for the path to determine if
4845 it is a symlink */
4846 if(is_directory &&
4847 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4848 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4849
4850 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004851 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4852 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4853 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4854 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004855 FindClose(find_data_handle);
4856 }
4857 }
4858 }
4859
4860 if (is_directory && is_link)
4861 return RemoveDirectoryW(lpFileName);
4862
4863 return DeleteFileW(lpFileName);
4864}
4865#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004866
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004867
Larry Hastings2f936352014-08-05 14:04:04 +10004868/*[clinic input]
4869os.unlink
4870
4871 path: path_t
4872 *
4873 dir_fd: dir_fd(requires='unlinkat')=None
4874
4875Remove a file (same as remove()).
4876
4877If dir_fd is not None, it should be a file descriptor open to a directory,
4878 and path should be relative; path will then be relative to that directory.
4879dir_fd may not be implemented on your platform.
4880 If it is unavailable, using it will raise a NotImplementedError.
4881
4882[clinic start generated code]*/
4883
Larry Hastings2f936352014-08-05 14:04:04 +10004884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004885os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4886/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004887{
4888 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01004889#ifdef HAVE_UNLINKAT
4890 int unlinkat_unavailable = 0;
4891#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004892
Saiyang Gou7514f4f2020-02-12 23:47:42 -08004893 if (PySys_Audit("os.remove", "Oi", path->object,
4894 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
4895 return NULL;
4896 }
4897
Larry Hastings9cf065c2012-06-22 16:30:09 -07004898 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004899 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004900#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004901 /* Windows, success=1, UNIX, success=0 */
4902 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004903#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004904#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01004905 if (dir_fd != DEFAULT_DIR_FD) {
4906 if (HAVE_UNLINKAT_RUNTIME) {
4907
Larry Hastings2f936352014-08-05 14:04:04 +10004908 result = unlinkat(dir_fd, path->narrow, 0);
Ronald Oussoren41761932020-11-08 10:05:27 +01004909 } else {
4910 unlinkat_unavailable = 1;
4911 }
4912 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004913#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004914 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004915#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004916 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004917 Py_END_ALLOW_THREADS
4918
Ronald Oussoren41761932020-11-08 10:05:27 +01004919#ifdef HAVE_UNLINKAT
4920 if (unlinkat_unavailable) {
4921 argument_unavailable_error(NULL, "dir_fd");
4922 return NULL;
4923 }
4924#endif
4925
Larry Hastings2f936352014-08-05 14:04:04 +10004926 if (result)
4927 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004928
Larry Hastings2f936352014-08-05 14:04:04 +10004929 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004930}
4931
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004932
Larry Hastings2f936352014-08-05 14:04:04 +10004933/*[clinic input]
4934os.remove = os.unlink
4935
4936Remove a file (same as unlink()).
4937
4938If dir_fd is not None, it should be a file descriptor open to a directory,
4939 and path should be relative; path will then be relative to that directory.
4940dir_fd may not be implemented on your platform.
4941 If it is unavailable, using it will raise a NotImplementedError.
4942[clinic start generated code]*/
4943
Larry Hastings2f936352014-08-05 14:04:04 +10004944static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004945os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4946/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004947{
4948 return os_unlink_impl(module, path, dir_fd);
4949}
4950
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004951
Larry Hastings605a62d2012-06-24 04:33:36 -07004952static PyStructSequence_Field uname_result_fields[] = {
4953 {"sysname", "operating system name"},
4954 {"nodename", "name of machine on network (implementation-defined)"},
4955 {"release", "operating system release"},
4956 {"version", "operating system version"},
4957 {"machine", "hardware identifier"},
4958 {NULL}
4959};
4960
4961PyDoc_STRVAR(uname_result__doc__,
4962"uname_result: Result from os.uname().\n\n\
4963This object may be accessed either as a tuple of\n\
4964 (sysname, nodename, release, version, machine),\n\
4965or via the attributes sysname, nodename, release, version, and machine.\n\
4966\n\
4967See os.uname for more information.");
4968
4969static PyStructSequence_Desc uname_result_desc = {
Eddie Elizondob3966632019-11-05 07:16:14 -08004970 MODNAME ".uname_result", /* name */
Larry Hastings605a62d2012-06-24 04:33:36 -07004971 uname_result__doc__, /* doc */
4972 uname_result_fields,
4973 5
4974};
4975
Larry Hastings605a62d2012-06-24 04:33:36 -07004976#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004977/*[clinic input]
4978os.uname
4979
4980Return an object identifying the current operating system.
4981
4982The object behaves like a named tuple with the following fields:
4983 (sysname, nodename, release, version, machine)
4984
4985[clinic start generated code]*/
4986
Larry Hastings2f936352014-08-05 14:04:04 +10004987static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004988os_uname_impl(PyObject *module)
4989/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004990{
Victor Stinner8c62be82010-05-06 00:08:46 +00004991 struct utsname u;
4992 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004993 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004994
Victor Stinner8c62be82010-05-06 00:08:46 +00004995 Py_BEGIN_ALLOW_THREADS
4996 res = uname(&u);
4997 Py_END_ALLOW_THREADS
4998 if (res < 0)
4999 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07005000
Hai Shif707d942020-03-16 21:15:01 +08005001 PyObject *UnameResultType = get_posix_state(module)->UnameResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08005002 value = PyStructSequence_New((PyTypeObject *)UnameResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07005003 if (value == NULL)
5004 return NULL;
5005
5006#define SET(i, field) \
5007 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02005008 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07005009 if (!o) { \
5010 Py_DECREF(value); \
5011 return NULL; \
5012 } \
5013 PyStructSequence_SET_ITEM(value, i, o); \
5014 } \
5015
5016 SET(0, u.sysname);
5017 SET(1, u.nodename);
5018 SET(2, u.release);
5019 SET(3, u.version);
5020 SET(4, u.machine);
5021
5022#undef SET
5023
5024 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00005025}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005026#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005027
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005028
Larry Hastings9cf065c2012-06-22 16:30:09 -07005029
5030typedef struct {
5031 int now;
5032 time_t atime_s;
5033 long atime_ns;
5034 time_t mtime_s;
5035 long mtime_ns;
5036} utime_t;
5037
5038/*
Victor Stinner484df002014-10-09 13:52:31 +02005039 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07005040 * they also intentionally leak the declaration of a pointer named "time"
5041 */
5042#define UTIME_TO_TIMESPEC \
5043 struct timespec ts[2]; \
5044 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005045 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005046 time = NULL; \
5047 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005048 ts[0].tv_sec = ut->atime_s; \
5049 ts[0].tv_nsec = ut->atime_ns; \
5050 ts[1].tv_sec = ut->mtime_s; \
5051 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005052 time = ts; \
5053 } \
5054
5055#define UTIME_TO_TIMEVAL \
5056 struct timeval tv[2]; \
5057 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005058 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005059 time = NULL; \
5060 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005061 tv[0].tv_sec = ut->atime_s; \
5062 tv[0].tv_usec = ut->atime_ns / 1000; \
5063 tv[1].tv_sec = ut->mtime_s; \
5064 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005065 time = tv; \
5066 } \
5067
5068#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005069 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005070 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005071 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005072 time = NULL; \
5073 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005074 u.actime = ut->atime_s; \
5075 u.modtime = ut->mtime_s; \
5076 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005077 }
5078
5079#define UTIME_TO_TIME_T \
5080 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005081 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02005082 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005083 time = NULL; \
5084 else { \
Victor Stinner484df002014-10-09 13:52:31 +02005085 timet[0] = ut->atime_s; \
5086 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02005087 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07005088 } \
5089
5090
Victor Stinner528a9ab2015-09-03 21:30:26 +02005091#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005092
5093static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005094utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005095{
Ronald Oussoren41761932020-11-08 10:05:27 +01005096#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5097 if (HAVE_UTIMENSAT_RUNTIME) {
5098 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5099 UTIME_TO_TIMESPEC;
5100 return utimensat(dir_fd, path, time, flags);
5101 } else {
5102 errno = ENOSYS;
5103 return -1;
5104 }
5105#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005106 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
5107 UTIME_TO_TIMESPEC;
5108 return utimensat(dir_fd, path, time, flags);
5109#elif defined(HAVE_FUTIMESAT)
5110 UTIME_TO_TIMEVAL;
5111 /*
5112 * follow_symlinks will never be false here;
5113 * we only allow !follow_symlinks and dir_fd together
5114 * if we have utimensat()
5115 */
5116 assert(follow_symlinks);
5117 return futimesat(dir_fd, path, time);
5118#endif
5119}
5120
Larry Hastings2f936352014-08-05 14:04:04 +10005121 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
5122#else
5123 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07005124#endif
5125
Victor Stinner528a9ab2015-09-03 21:30:26 +02005126#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005127
5128static int
Victor Stinner484df002014-10-09 13:52:31 +02005129utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005130{
5131#ifdef HAVE_FUTIMENS
Ronald Oussoren41761932020-11-08 10:05:27 +01005132
5133 if (HAVE_FUTIMENS_RUNTIME) {
5134
Larry Hastings9cf065c2012-06-22 16:30:09 -07005135 UTIME_TO_TIMESPEC;
5136 return futimens(fd, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005137
5138 } else
5139#ifndef HAVE_FUTIMES
5140 {
5141 /* Not sure if this can happen */
5142 PyErr_SetString(
5143 PyExc_RuntimeError,
5144 "neither futimens nor futimes are supported"
5145 " on this system");
5146 return -1;
5147 }
5148#endif
5149
5150#endif
5151#ifdef HAVE_FUTIMES
5152 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005153 UTIME_TO_TIMEVAL;
5154 return futimes(fd, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005155 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005156#endif
5157}
5158
Larry Hastings2f936352014-08-05 14:04:04 +10005159 #define PATH_UTIME_HAVE_FD 1
5160#else
5161 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07005162#endif
5163
Victor Stinner5ebae872015-09-22 01:29:33 +02005164#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
5165# define UTIME_HAVE_NOFOLLOW_SYMLINKS
5166#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005167
Victor Stinner4552ced2015-09-21 22:37:15 +02005168#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005169
5170static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005171utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005172{
5173#ifdef HAVE_UTIMENSAT
Ronald Oussoren41761932020-11-08 10:05:27 +01005174 if (HAVE_UTIMENSAT_RUNTIME) {
5175 UTIME_TO_TIMESPEC;
5176 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
5177 } else
5178#ifndef HAVE_LUTIMES
5179 {
5180 /* Not sure if this can happen */
5181 PyErr_SetString(
5182 PyExc_RuntimeError,
5183 "neither utimensat nor lutimes are supported"
5184 " on this system");
5185 return -1;
5186 }
5187#endif
5188#endif
5189
5190#ifdef HAVE_LUTIMES
5191 {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005192 UTIME_TO_TIMEVAL;
5193 return lutimes(path, time);
Ronald Oussoren41761932020-11-08 10:05:27 +01005194 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005195#endif
5196}
5197
5198#endif
5199
5200#ifndef MS_WINDOWS
5201
5202static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02005203utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005204{
Ronald Oussoren41761932020-11-08 10:05:27 +01005205#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5206 if (HAVE_UTIMENSAT_RUNTIME) {
5207 UTIME_TO_TIMESPEC;
5208 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5209 } else {
5210 UTIME_TO_TIMEVAL;
5211 return utimes(path, time);
5212 }
5213#elif defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005214 UTIME_TO_TIMESPEC;
5215 return utimensat(DEFAULT_DIR_FD, path, time, 0);
5216#elif defined(HAVE_UTIMES)
5217 UTIME_TO_TIMEVAL;
5218 return utimes(path, time);
5219#elif defined(HAVE_UTIME_H)
5220 UTIME_TO_UTIMBUF;
5221 return utime(path, time);
5222#else
5223 UTIME_TO_TIME_T;
5224 return utime(path, time);
5225#endif
5226}
5227
5228#endif
5229
Larry Hastings76ad59b2012-05-03 00:30:07 -07005230static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005231split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns)
Larry Hastings76ad59b2012-05-03 00:30:07 -07005232{
5233 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04005234 PyObject *divmod;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005235 divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion);
Larry Hastings76ad59b2012-05-03 00:30:07 -07005236 if (!divmod)
5237 goto exit;
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005238 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
5239 PyErr_Format(PyExc_TypeError,
5240 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -08005241 _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod)));
Oren Milman0bd1a2d2018-09-12 22:14:35 +03005242 goto exit;
5243 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005244 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
5245 if ((*s == -1) && PyErr_Occurred())
5246 goto exit;
5247 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04005248 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07005249 goto exit;
5250
5251 result = 1;
5252exit:
5253 Py_XDECREF(divmod);
5254 return result;
5255}
5256
Larry Hastings2f936352014-08-05 14:04:04 +10005257
5258/*[clinic input]
5259os.utime
5260
5261 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005262 times: object = None
Larry Hastings2f936352014-08-05 14:04:04 +10005263 *
5264 ns: object = NULL
5265 dir_fd: dir_fd(requires='futimensat') = None
5266 follow_symlinks: bool=True
5267
Martin Panter0ff89092015-09-09 01:56:53 +00005268# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10005269
5270Set the access and modified time of path.
5271
5272path may always be specified as a string.
5273On some platforms, path may also be specified as an open file descriptor.
5274 If this functionality is unavailable, using it raises an exception.
5275
5276If times is not None, it must be a tuple (atime, mtime);
5277 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005278If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10005279 atime_ns and mtime_ns should be expressed as integer nanoseconds
5280 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00005281If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10005282Specifying tuples for both times and ns is an error.
5283
5284If dir_fd is not None, it should be a file descriptor open to a directory,
5285 and path should be relative; path will then be relative to that directory.
5286If follow_symlinks is False, and the last element of the path is a symbolic
5287 link, utime will modify the symbolic link itself instead of the file the
5288 link points to.
5289It is an error to use dir_fd or follow_symlinks when specifying path
5290 as an open file descriptor.
5291dir_fd and follow_symlinks may not be available on your platform.
5292 If they are unavailable, using them will raise a NotImplementedError.
5293
5294[clinic start generated code]*/
5295
Larry Hastings2f936352014-08-05 14:04:04 +10005296static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005297os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
5298 int dir_fd, int follow_symlinks)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005299/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005300{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005301#ifdef MS_WINDOWS
5302 HANDLE hFile;
5303 FILETIME atime, mtime;
5304#else
5305 int result;
5306#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005307
Larry Hastings2f936352014-08-05 14:04:04 +10005308 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005309
Christian Heimesb3c87242013-08-01 00:08:16 +02005310 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07005311
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005312 if (times != Py_None && ns) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005313 PyErr_SetString(PyExc_ValueError,
5314 "utime: you may specify either 'times'"
5315 " or 'ns' but not both");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005316 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005317 }
5318
Serhiy Storchaka279f4462019-09-14 12:24:05 +03005319 if (times != Py_None) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005320 time_t a_sec, m_sec;
5321 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005322 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005323 PyErr_SetString(PyExc_TypeError,
5324 "utime: 'times' must be either"
5325 " a tuple of two ints or None");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005326 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005327 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005328 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005329 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005330 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005331 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02005332 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005333 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005334 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02005335 utime.atime_s = a_sec;
5336 utime.atime_ns = a_nsec;
5337 utime.mtime_s = m_sec;
5338 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005339 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005340 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07005341 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005342 PyErr_SetString(PyExc_TypeError,
5343 "utime: 'ns' must be a tuple of two ints");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005344 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005345 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005346 utime.now = 0;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005347 if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005348 &utime.atime_s, &utime.atime_ns) ||
Victor Stinner1c2fa782020-05-10 11:05:29 +02005349 !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07005350 &utime.mtime_s, &utime.mtime_ns)) {
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005351 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005352 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07005353 }
5354 else {
5355 /* times and ns are both None/unspecified. use "now". */
5356 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005357 }
5358
Victor Stinner4552ced2015-09-21 22:37:15 +02005359#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07005360 if (follow_symlinks_specified("utime", follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005361 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005362#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04005363
Larry Hastings2f936352014-08-05 14:04:04 +10005364 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
5365 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
5366 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005367 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07005368
Larry Hastings9cf065c2012-06-22 16:30:09 -07005369#if !defined(HAVE_UTIMENSAT)
5370 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02005371 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005372 "utime: cannot use dir_fd and follow_symlinks "
5373 "together on this platform");
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005374 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005375 }
5376#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07005377
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005378 if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None,
5379 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
5380 return NULL;
5381 }
5382
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005383#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005384 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005385 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
5386 NULL, OPEN_EXISTING,
5387 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005388 Py_END_ALLOW_THREADS
5389 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10005390 path_error(path);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005391 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07005392 }
5393
Larry Hastings9cf065c2012-06-22 16:30:09 -07005394 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01005395 GetSystemTimeAsFileTime(&mtime);
5396 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00005397 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08005399 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
5400 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00005401 }
5402 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
5403 /* Avoid putting the file name into the error here,
5404 as that may confuse the user into believing that
5405 something is wrong with the file, when it also
5406 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01005407 PyErr_SetFromWindowsErr(0);
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005408 CloseHandle(hFile);
5409 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 }
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005411 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005412#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005413 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00005414
Victor Stinner4552ced2015-09-21 22:37:15 +02005415#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07005416 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10005417 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005418 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07005419#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07005420
Victor Stinner528a9ab2015-09-03 21:30:26 +02005421#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Ronald Oussoren41761932020-11-08 10:05:27 +01005422 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) {
Larry Hastings2f936352014-08-05 14:04:04 +10005423 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Ronald Oussoren41761932020-11-08 10:05:27 +01005424
5425 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07005426#endif
5427
Victor Stinner528a9ab2015-09-03 21:30:26 +02005428#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10005429 if (path->fd != -1)
5430 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005431 else
5432#endif
5433
Larry Hastings2f936352014-08-05 14:04:04 +10005434 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005435
5436 Py_END_ALLOW_THREADS
5437
Ronald Oussoren41761932020-11-08 10:05:27 +01005438#if defined(__APPLE__) && defined(HAVE_UTIMENSAT)
5439 /* See utime_dir_fd implementation */
5440 if (result == -1 && errno == ENOSYS) {
5441 argument_unavailable_error(NULL, "dir_fd");
5442 return NULL;
5443 }
5444#endif
5445
Larry Hastings9cf065c2012-06-22 16:30:09 -07005446 if (result < 0) {
5447 /* see previous comment about not putting filename in error here */
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005448 posix_error();
5449 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005450 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07005451
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00005452#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07005453
Serhiy Storchaka32bc11c2018-12-01 14:30:20 +02005454 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005455}
5456
Guido van Rossum3b066191991-06-04 19:40:25 +00005457/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005458
Larry Hastings2f936352014-08-05 14:04:04 +10005459
5460/*[clinic input]
5461os._exit
5462
5463 status: int
5464
5465Exit to the system with specified status, without normal exit processing.
5466[clinic start generated code]*/
5467
Larry Hastings2f936352014-08-05 14:04:04 +10005468static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005469os__exit_impl(PyObject *module, int status)
5470/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005471{
5472 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00005473 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005474}
5475
Steve Dowercc16be82016-09-08 10:35:16 -07005476#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5477#define EXECV_CHAR wchar_t
5478#else
5479#define EXECV_CHAR char
5480#endif
5481
pxinwrf2d7ac72019-05-21 18:46:37 +08005482#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005483static void
Steve Dowercc16be82016-09-08 10:35:16 -07005484free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00005485{
Victor Stinner8c62be82010-05-06 00:08:46 +00005486 Py_ssize_t i;
5487 for (i = 0; i < count; i++)
5488 PyMem_Free(array[i]);
Victor Stinner00d7abd2020-12-01 09:56:42 +01005489 PyMem_Free(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005490}
Martin v. Löwis011e8422009-05-05 04:43:17 +00005491
Berker Peksag81816462016-09-15 20:19:47 +03005492static int
5493fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00005494{
Victor Stinner8c62be82010-05-06 00:08:46 +00005495 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03005496 PyObject *ub;
5497 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07005498#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03005499 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07005500 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005501 *out = PyUnicode_AsWideCharString(ub, &size);
5502 if (*out)
5503 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07005504#else
Berker Peksag81816462016-09-15 20:19:47 +03005505 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00005506 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03005507 size = PyBytes_GET_SIZE(ub);
5508 *out = PyMem_Malloc(size + 1);
5509 if (*out) {
5510 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
5511 result = 1;
5512 } else
Victor Stinner50abf222013-11-07 23:56:10 +01005513 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07005514#endif
Berker Peksag81816462016-09-15 20:19:47 +03005515 Py_DECREF(ub);
5516 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005517}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005518#endif
5519
pxinwrf2d7ac72019-05-21 18:46:37 +08005520#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN)
Steve Dowercc16be82016-09-08 10:35:16 -07005521static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00005522parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5523{
Victor Stinner8c62be82010-05-06 00:08:46 +00005524 Py_ssize_t i, pos, envc;
5525 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03005526 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07005527 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005528
Victor Stinner8c62be82010-05-06 00:08:46 +00005529 i = PyMapping_Size(env);
5530 if (i < 0)
5531 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07005532 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005533 if (envlist == NULL) {
5534 PyErr_NoMemory();
5535 return NULL;
5536 }
5537 envc = 0;
5538 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005539 if (!keys)
5540 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005541 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005542 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005543 goto error;
5544 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5545 PyErr_Format(PyExc_TypeError,
5546 "env.keys() or env.values() is not a list");
5547 goto error;
5548 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005549
Victor Stinner8c62be82010-05-06 00:08:46 +00005550 for (pos = 0; pos < i; pos++) {
5551 key = PyList_GetItem(keys, pos);
5552 val = PyList_GetItem(vals, pos);
5553 if (!key || !val)
5554 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005555
Berker Peksag81816462016-09-15 20:19:47 +03005556#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
5557 if (!PyUnicode_FSDecoder(key, &key2))
5558 goto error;
5559 if (!PyUnicode_FSDecoder(val, &val2)) {
5560 Py_DECREF(key2);
5561 goto error;
5562 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005563 /* Search from index 1 because on Windows starting '=' is allowed for
5564 defining hidden environment variables. */
5565 if (PyUnicode_GET_LENGTH(key2) == 0 ||
5566 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
5567 {
5568 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005569 Py_DECREF(key2);
5570 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005571 goto error;
5572 }
Berker Peksag81816462016-09-15 20:19:47 +03005573 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
5574#else
5575 if (!PyUnicode_FSConverter(key, &key2))
5576 goto error;
5577 if (!PyUnicode_FSConverter(val, &val2)) {
5578 Py_DECREF(key2);
5579 goto error;
5580 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03005581 if (PyBytes_GET_SIZE(key2) == 0 ||
5582 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
5583 {
5584 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04005585 Py_DECREF(key2);
5586 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03005587 goto error;
5588 }
Berker Peksag81816462016-09-15 20:19:47 +03005589 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
5590 PyBytes_AS_STRING(val2));
5591#endif
5592 Py_DECREF(key2);
5593 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07005594 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00005595 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07005596
5597 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
5598 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005599 goto error;
5600 }
Berker Peksag81816462016-09-15 20:19:47 +03005601
Steve Dowercc16be82016-09-08 10:35:16 -07005602 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00005603 }
5604 Py_DECREF(vals);
5605 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005606
Victor Stinner8c62be82010-05-06 00:08:46 +00005607 envlist[envc] = 0;
5608 *envc_ptr = envc;
5609 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005610
5611error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005612 Py_XDECREF(keys);
5613 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07005614 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005615 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005616}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005617
Steve Dowercc16be82016-09-08 10:35:16 -07005618static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02005619parse_arglist(PyObject* argv, Py_ssize_t *argc)
5620{
5621 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07005622 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005623 if (argvlist == NULL) {
5624 PyErr_NoMemory();
5625 return NULL;
5626 }
5627 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005628 PyObject* item = PySequence_ITEM(argv, i);
5629 if (item == NULL)
5630 goto fail;
5631 if (!fsconvert_strdup(item, &argvlist[i])) {
5632 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005633 goto fail;
5634 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005635 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005636 }
5637 argvlist[*argc] = NULL;
5638 return argvlist;
5639fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005640 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005641 free_string_array(argvlist, *argc);
5642 return NULL;
5643}
Steve Dowercc16be82016-09-08 10:35:16 -07005644
Ross Lagerwall7807c352011-03-17 20:20:30 +02005645#endif
5646
Larry Hastings2f936352014-08-05 14:04:04 +10005647
Ross Lagerwall7807c352011-03-17 20:20:30 +02005648#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005649/*[clinic input]
5650os.execv
5651
Steve Dowercc16be82016-09-08 10:35:16 -07005652 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005653 Path of executable file.
5654 argv: object
5655 Tuple or list of strings.
5656 /
5657
5658Execute an executable path with arguments, replacing current process.
5659[clinic start generated code]*/
5660
Larry Hastings2f936352014-08-05 14:04:04 +10005661static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005662os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
5663/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005664{
Steve Dowercc16be82016-09-08 10:35:16 -07005665 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005666 Py_ssize_t argc;
5667
5668 /* execv has two arguments: (path, argv), where
5669 argv is a list or tuple of strings. */
5670
Ross Lagerwall7807c352011-03-17 20:20:30 +02005671 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5672 PyErr_SetString(PyExc_TypeError,
5673 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005674 return NULL;
5675 }
5676 argc = PySequence_Size(argv);
5677 if (argc < 1) {
5678 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005679 return NULL;
5680 }
5681
5682 argvlist = parse_arglist(argv, &argc);
5683 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005684 return NULL;
5685 }
Steve Dowerbce26262016-11-19 19:17:26 -08005686 if (!argvlist[0][0]) {
5687 PyErr_SetString(PyExc_ValueError,
5688 "execv() arg 2 first element cannot be empty");
5689 free_string_array(argvlist, argc);
5690 return NULL;
5691 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005692
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005693 if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005694 free_string_array(argvlist, argc);
5695 return NULL;
5696 }
5697
Steve Dowerbce26262016-11-19 19:17:26 -08005698 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005699#ifdef HAVE_WEXECV
5700 _wexecv(path->wide, argvlist);
5701#else
5702 execv(path->narrow, argvlist);
5703#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005704 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005705
5706 /* If we get here it's definitely an error */
5707
5708 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005709 return posix_error();
5710}
5711
Larry Hastings2f936352014-08-05 14:04:04 +10005712
5713/*[clinic input]
5714os.execve
5715
5716 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5717 Path of executable file.
5718 argv: object
5719 Tuple or list of strings.
5720 env: object
5721 Dictionary of strings mapping to strings.
5722
5723Execute an executable path with arguments, replacing current process.
5724[clinic start generated code]*/
5725
Larry Hastings2f936352014-08-05 14:04:04 +10005726static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005727os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5728/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005729{
Steve Dowercc16be82016-09-08 10:35:16 -07005730 EXECV_CHAR **argvlist = NULL;
5731 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005732 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005733
Victor Stinner8c62be82010-05-06 00:08:46 +00005734 /* execve has three arguments: (path, argv, env), where
5735 argv is a list or tuple of strings and env is a dictionary
5736 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005737
Ross Lagerwall7807c352011-03-17 20:20:30 +02005738 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005740 "execve: argv must be a tuple or list");
Saiyang Gou95f60012020-02-04 16:15:00 -08005741 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005742 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005743 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005744 if (argc < 1) {
5745 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5746 return NULL;
5747 }
5748
Victor Stinner8c62be82010-05-06 00:08:46 +00005749 if (!PyMapping_Check(env)) {
5750 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005751 "execve: environment must be a mapping object");
Saiyang Gou95f60012020-02-04 16:15:00 -08005752 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005753 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005754
Ross Lagerwall7807c352011-03-17 20:20:30 +02005755 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005756 if (argvlist == NULL) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005757 goto fail_0;
Victor Stinner8c62be82010-05-06 00:08:46 +00005758 }
Steve Dowerbce26262016-11-19 19:17:26 -08005759 if (!argvlist[0][0]) {
5760 PyErr_SetString(PyExc_ValueError,
5761 "execve: argv first element cannot be empty");
Saiyang Gou95f60012020-02-04 16:15:00 -08005762 goto fail_0;
Steve Dowerbce26262016-11-19 19:17:26 -08005763 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005764
Victor Stinner8c62be82010-05-06 00:08:46 +00005765 envlist = parse_envlist(env, &envc);
5766 if (envlist == NULL)
Saiyang Gou95f60012020-02-04 16:15:00 -08005767 goto fail_0;
5768
Saiyang Gou7514f4f2020-02-12 23:47:42 -08005769 if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08005770 goto fail_1;
5771 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005772
Steve Dowerbce26262016-11-19 19:17:26 -08005773 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005774#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005775 if (path->fd > -1)
5776 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005777 else
5778#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005779#ifdef HAVE_WEXECV
5780 _wexecve(path->wide, argvlist, envlist);
5781#else
Larry Hastings2f936352014-08-05 14:04:04 +10005782 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005783#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005784 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005785
5786 /* If we get here it's definitely an error */
5787
Alexey Izbyshev83460312018-10-20 03:28:22 +03005788 posix_path_error(path);
Saiyang Gou95f60012020-02-04 16:15:00 -08005789 fail_1:
Steve Dowercc16be82016-09-08 10:35:16 -07005790 free_string_array(envlist, envc);
Saiyang Gou95f60012020-02-04 16:15:00 -08005791 fail_0:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005792 if (argvlist)
5793 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005794 return NULL;
5795}
Steve Dowercc16be82016-09-08 10:35:16 -07005796
Larry Hastings9cf065c2012-06-22 16:30:09 -07005797#endif /* HAVE_EXECV */
5798
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00005799#ifdef HAVE_POSIX_SPAWN
5800
5801enum posix_spawn_file_actions_identifier {
5802 POSIX_SPAWN_OPEN,
5803 POSIX_SPAWN_CLOSE,
5804 POSIX_SPAWN_DUP2
5805};
5806
William Orr81574b82018-10-01 22:19:56 -07005807#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005808static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005809convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res);
William Orr81574b82018-10-01 22:19:56 -07005810#endif
Pablo Galindo254a4662018-09-07 16:44:24 +01005811
5812static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02005813parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup,
Victor Stinner325e4ba2019-02-01 15:47:24 +01005814 int resetids, int setsid, PyObject *setsigmask,
Pablo Galindo254a4662018-09-07 16:44:24 +01005815 PyObject *setsigdef, PyObject *scheduler,
5816 posix_spawnattr_t *attrp)
5817{
5818 long all_flags = 0;
5819
5820 errno = posix_spawnattr_init(attrp);
5821 if (errno) {
5822 posix_error();
5823 return -1;
5824 }
5825
5826 if (setpgroup) {
5827 pid_t pgid = PyLong_AsPid(setpgroup);
5828 if (pgid == (pid_t)-1 && PyErr_Occurred()) {
5829 goto fail;
5830 }
5831 errno = posix_spawnattr_setpgroup(attrp, pgid);
5832 if (errno) {
5833 posix_error();
5834 goto fail;
5835 }
5836 all_flags |= POSIX_SPAWN_SETPGROUP;
5837 }
5838
5839 if (resetids) {
5840 all_flags |= POSIX_SPAWN_RESETIDS;
5841 }
5842
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005843 if (setsid) {
Ronald Oussoren41761932020-11-08 10:05:27 +01005844#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5845 if (HAVE_POSIX_SPAWN_SETSID_RUNTIME) {
5846#endif
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005847#ifdef POSIX_SPAWN_SETSID
5848 all_flags |= POSIX_SPAWN_SETSID;
5849#elif defined(POSIX_SPAWN_SETSID_NP)
5850 all_flags |= POSIX_SPAWN_SETSID_NP;
5851#else
5852 argument_unavailable_error(func_name, "setsid");
5853 return -1;
5854#endif
Ronald Oussoren41761932020-11-08 10:05:27 +01005855
5856#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME
5857 } else {
5858 argument_unavailable_error(func_name, "setsid");
5859 return -1;
5860 }
5861#endif /* HAVE_POSIX_SPAWN_SETSID_RUNTIME */
5862
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03005863 }
5864
Pablo Galindo254a4662018-09-07 16:44:24 +01005865 if (setsigmask) {
5866 sigset_t set;
5867 if (!_Py_Sigset_Converter(setsigmask, &set)) {
5868 goto fail;
5869 }
5870 errno = posix_spawnattr_setsigmask(attrp, &set);
5871 if (errno) {
5872 posix_error();
5873 goto fail;
5874 }
5875 all_flags |= POSIX_SPAWN_SETSIGMASK;
5876 }
5877
5878 if (setsigdef) {
5879 sigset_t set;
5880 if (!_Py_Sigset_Converter(setsigdef, &set)) {
5881 goto fail;
5882 }
5883 errno = posix_spawnattr_setsigdefault(attrp, &set);
5884 if (errno) {
5885 posix_error();
5886 goto fail;
5887 }
5888 all_flags |= POSIX_SPAWN_SETSIGDEF;
5889 }
5890
5891 if (scheduler) {
5892#ifdef POSIX_SPAWN_SETSCHEDULER
5893 PyObject *py_schedpolicy;
Victor Stinner1c2fa782020-05-10 11:05:29 +02005894 PyObject *schedparam_obj;
Pablo Galindo254a4662018-09-07 16:44:24 +01005895 struct sched_param schedparam;
5896
Victor Stinner1c2fa782020-05-10 11:05:29 +02005897 if (!PyArg_ParseTuple(scheduler, "OO"
Pablo Galindo254a4662018-09-07 16:44:24 +01005898 ";A scheduler tuple must have two elements",
Victor Stinner1c2fa782020-05-10 11:05:29 +02005899 &py_schedpolicy, &schedparam_obj)) {
5900 goto fail;
5901 }
5902 if (!convert_sched_param(module, schedparam_obj, &schedparam)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01005903 goto fail;
5904 }
5905 if (py_schedpolicy != Py_None) {
5906 int schedpolicy = _PyLong_AsInt(py_schedpolicy);
5907
5908 if (schedpolicy == -1 && PyErr_Occurred()) {
5909 goto fail;
5910 }
5911 errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy);
5912 if (errno) {
5913 posix_error();
5914 goto fail;
5915 }
5916 all_flags |= POSIX_SPAWN_SETSCHEDULER;
5917 }
5918 errno = posix_spawnattr_setschedparam(attrp, &schedparam);
5919 if (errno) {
5920 posix_error();
5921 goto fail;
5922 }
5923 all_flags |= POSIX_SPAWN_SETSCHEDPARAM;
5924#else
5925 PyErr_SetString(PyExc_NotImplementedError,
5926 "The scheduler option is not supported in this system.");
5927 goto fail;
5928#endif
5929 }
5930
5931 errno = posix_spawnattr_setflags(attrp, all_flags);
5932 if (errno) {
5933 posix_error();
5934 goto fail;
5935 }
5936
5937 return 0;
5938
5939fail:
5940 (void)posix_spawnattr_destroy(attrp);
5941 return -1;
5942}
5943
5944static int
Serhiy Storchakaef347532018-05-01 16:45:04 +03005945parse_file_actions(PyObject *file_actions,
Pablo Galindocb970732018-06-19 09:19:50 +01005946 posix_spawn_file_actions_t *file_actionsp,
5947 PyObject *temp_buffer)
Serhiy Storchakaef347532018-05-01 16:45:04 +03005948{
5949 PyObject *seq;
5950 PyObject *file_action = NULL;
5951 PyObject *tag_obj;
5952
5953 seq = PySequence_Fast(file_actions,
5954 "file_actions must be a sequence or None");
5955 if (seq == NULL) {
5956 return -1;
5957 }
5958
5959 errno = posix_spawn_file_actions_init(file_actionsp);
5960 if (errno) {
5961 posix_error();
5962 Py_DECREF(seq);
5963 return -1;
5964 }
5965
Zackery Spytzd52a83a2019-06-26 14:54:20 -06005966 for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) {
Serhiy Storchakaef347532018-05-01 16:45:04 +03005967 file_action = PySequence_Fast_GET_ITEM(seq, i);
5968 Py_INCREF(file_action);
5969 if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) {
5970 PyErr_SetString(PyExc_TypeError,
5971 "Each file_actions element must be a non-empty tuple");
5972 goto fail;
5973 }
5974 long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0));
5975 if (tag == -1 && PyErr_Occurred()) {
5976 goto fail;
5977 }
5978
5979 /* Populate the file_actions object */
5980 switch (tag) {
5981 case POSIX_SPAWN_OPEN: {
5982 int fd, oflag;
5983 PyObject *path;
5984 unsigned long mode;
5985 if (!PyArg_ParseTuple(file_action, "OiO&ik"
5986 ";A open file_action tuple must have 5 elements",
5987 &tag_obj, &fd, PyUnicode_FSConverter, &path,
5988 &oflag, &mode))
5989 {
5990 goto fail;
5991 }
Pablo Galindocb970732018-06-19 09:19:50 +01005992 if (PyList_Append(temp_buffer, path)) {
5993 Py_DECREF(path);
5994 goto fail;
5995 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03005996 errno = posix_spawn_file_actions_addopen(file_actionsp,
5997 fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode);
Pablo Galindocb970732018-06-19 09:19:50 +01005998 Py_DECREF(path);
Serhiy Storchakaef347532018-05-01 16:45:04 +03005999 if (errno) {
6000 posix_error();
6001 goto fail;
6002 }
6003 break;
6004 }
6005 case POSIX_SPAWN_CLOSE: {
6006 int fd;
6007 if (!PyArg_ParseTuple(file_action, "Oi"
6008 ";A close file_action tuple must have 2 elements",
6009 &tag_obj, &fd))
6010 {
6011 goto fail;
6012 }
6013 errno = posix_spawn_file_actions_addclose(file_actionsp, fd);
6014 if (errno) {
6015 posix_error();
6016 goto fail;
6017 }
6018 break;
6019 }
6020 case POSIX_SPAWN_DUP2: {
6021 int fd1, fd2;
6022 if (!PyArg_ParseTuple(file_action, "Oii"
6023 ";A dup2 file_action tuple must have 3 elements",
6024 &tag_obj, &fd1, &fd2))
6025 {
6026 goto fail;
6027 }
6028 errno = posix_spawn_file_actions_adddup2(file_actionsp,
6029 fd1, fd2);
6030 if (errno) {
6031 posix_error();
6032 goto fail;
6033 }
6034 break;
6035 }
6036 default: {
6037 PyErr_SetString(PyExc_TypeError,
6038 "Unknown file_actions identifier");
6039 goto fail;
6040 }
6041 }
6042 Py_DECREF(file_action);
6043 }
Pablo Galindo254a4662018-09-07 16:44:24 +01006044
Serhiy Storchakaef347532018-05-01 16:45:04 +03006045 Py_DECREF(seq);
6046 return 0;
6047
6048fail:
6049 Py_DECREF(seq);
6050 Py_DECREF(file_action);
6051 (void)posix_spawn_file_actions_destroy(file_actionsp);
6052 return -1;
6053}
6054
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006055
6056static PyObject *
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006057py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv,
6058 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006059 PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006060 PyObject *setsigdef, PyObject *scheduler)
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006061{
Victor Stinner325e4ba2019-02-01 15:47:24 +01006062 const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn";
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006063 EXECV_CHAR **argvlist = NULL;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006064 EXECV_CHAR **envlist = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006065 posix_spawn_file_actions_t file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006066 posix_spawn_file_actions_t *file_actionsp = NULL;
Pablo Galindo254a4662018-09-07 16:44:24 +01006067 posix_spawnattr_t attr;
6068 posix_spawnattr_t *attrp = NULL;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006069 Py_ssize_t argc, envc;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006070 PyObject *result = NULL;
Pablo Galindocb970732018-06-19 09:19:50 +01006071 PyObject *temp_buffer = NULL;
Serhiy Storchakaef347532018-05-01 16:45:04 +03006072 pid_t pid;
6073 int err_code;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006074
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006075 /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where
Serhiy Storchakaef347532018-05-01 16:45:04 +03006076 argv is a list or tuple of strings and env is a dictionary
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006077 like posix.environ. */
6078
Serhiy Storchakaef347532018-05-01 16:45:04 +03006079 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006080 PyErr_Format(PyExc_TypeError,
6081 "%s: argv must be a tuple or list", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006082 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006083 }
6084 argc = PySequence_Size(argv);
6085 if (argc < 1) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006086 PyErr_Format(PyExc_ValueError,
6087 "%s: argv must not be empty", func_name);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006088 return NULL;
6089 }
6090
6091 if (!PyMapping_Check(env)) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006092 PyErr_Format(PyExc_TypeError,
6093 "%s: environment must be a mapping object", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006094 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006095 }
6096
6097 argvlist = parse_arglist(argv, &argc);
6098 if (argvlist == NULL) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006099 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006100 }
6101 if (!argvlist[0][0]) {
Victor Stinner325e4ba2019-02-01 15:47:24 +01006102 PyErr_Format(PyExc_ValueError,
6103 "%s: argv first element cannot be empty", func_name);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006104 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006105 }
6106
6107 envlist = parse_envlist(env, &envc);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006108 if (envlist == NULL) {
6109 goto exit;
6110 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006111
Anthony Shaw948ed8c2019-05-10 12:00:06 +10006112 if (file_actions != NULL && file_actions != Py_None) {
Pablo Galindocb970732018-06-19 09:19:50 +01006113 /* There is a bug in old versions of glibc that makes some of the
6114 * helper functions for manipulating file actions not copy the provided
6115 * buffers. The problem is that posix_spawn_file_actions_addopen does not
6116 * copy the value of path for some old versions of glibc (<2.20).
6117 * The use of temp_buffer here is a workaround that keeps the
6118 * python objects that own the buffers alive until posix_spawn gets called.
6119 * Check https://bugs.python.org/issue33630 and
6120 * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/
6121 temp_buffer = PyList_New(0);
6122 if (!temp_buffer) {
6123 goto exit;
6124 }
6125 if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) {
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006126 goto exit;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006127 }
Serhiy Storchakaef347532018-05-01 16:45:04 +03006128 file_actionsp = &file_actions_buf;
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006129 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006130
Victor Stinner1c2fa782020-05-10 11:05:29 +02006131 if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid,
Victor Stinner325e4ba2019-02-01 15:47:24 +01006132 setsigmask, setsigdef, scheduler, &attr)) {
Pablo Galindo254a4662018-09-07 16:44:24 +01006133 goto exit;
6134 }
6135 attrp = &attr;
6136
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006137 if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006138 goto exit;
6139 }
6140
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006141 _Py_BEGIN_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006142#ifdef HAVE_POSIX_SPAWNP
6143 if (use_posix_spawnp) {
6144 err_code = posix_spawnp(&pid, path->narrow,
6145 file_actionsp, attrp, argvlist, envlist);
6146 }
6147 else
6148#endif /* HAVE_POSIX_SPAWNP */
6149 {
6150 err_code = posix_spawn(&pid, path->narrow,
6151 file_actionsp, attrp, argvlist, envlist);
6152 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006153 _Py_END_SUPPRESS_IPH
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006154
Serhiy Storchakaef347532018-05-01 16:45:04 +03006155 if (err_code) {
6156 errno = err_code;
6157 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006158 goto exit;
6159 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006160#ifdef _Py_MEMORY_SANITIZER
6161 __msan_unpoison(&pid, sizeof(pid));
6162#endif
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006163 result = PyLong_FromPid(pid);
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006164
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006165exit:
Serhiy Storchakaef347532018-05-01 16:45:04 +03006166 if (file_actionsp) {
6167 (void)posix_spawn_file_actions_destroy(file_actionsp);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006168 }
Pablo Galindo254a4662018-09-07 16:44:24 +01006169 if (attrp) {
6170 (void)posix_spawnattr_destroy(attrp);
6171 }
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006172 if (envlist) {
6173 free_string_array(envlist, envc);
6174 }
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006175 if (argvlist) {
6176 free_string_array(argvlist, argc);
6177 }
Pablo Galindocb970732018-06-19 09:19:50 +01006178 Py_XDECREF(temp_buffer);
Pablo Galindo0cd6bca2018-01-29 20:34:42 +00006179 return result;
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006180}
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006181
6182
6183/*[clinic input]
6184
6185os.posix_spawn
6186 path: path_t
6187 Path of executable file.
6188 argv: object
6189 Tuple or list of strings.
6190 env: object
6191 Dictionary of strings mapping to strings.
6192 /
6193 *
6194 file_actions: object(c_default='NULL') = ()
6195 A sequence of file action tuples.
6196 setpgroup: object = NULL
6197 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6198 resetids: bool(accept={int}) = False
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006199 If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
6200 setsid: bool(accept={int}) = False
6201 If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006202 setsigmask: object(c_default='NULL') = ()
6203 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6204 setsigdef: object(c_default='NULL') = ()
6205 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6206 scheduler: object = NULL
6207 A tuple with the scheduler policy (optional) and parameters.
6208
6209Execute the program specified by path in a new process.
6210[clinic start generated code]*/
6211
6212static PyObject *
6213os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
6214 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006215 PyObject *setpgroup, int resetids, int setsid,
6216 PyObject *setsigmask, PyObject *setsigdef,
6217 PyObject *scheduler)
6218/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006219{
6220 return py_posix_spawn(0, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006221 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006222 scheduler);
6223}
6224 #endif /* HAVE_POSIX_SPAWN */
6225
6226
6227
6228#ifdef HAVE_POSIX_SPAWNP
6229/*[clinic input]
6230
6231os.posix_spawnp
6232 path: path_t
6233 Path of executable file.
6234 argv: object
6235 Tuple or list of strings.
6236 env: object
6237 Dictionary of strings mapping to strings.
6238 /
6239 *
6240 file_actions: object(c_default='NULL') = ()
6241 A sequence of file action tuples.
6242 setpgroup: object = NULL
6243 The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
6244 resetids: bool(accept={int}) = False
6245 If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006246 setsid: bool(accept={int}) = False
6247 If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006248 setsigmask: object(c_default='NULL') = ()
6249 The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
6250 setsigdef: object(c_default='NULL') = ()
6251 The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
6252 scheduler: object = NULL
6253 A tuple with the scheduler policy (optional) and parameters.
6254
6255Execute the program specified by path in a new process.
6256[clinic start generated code]*/
6257
6258static PyObject *
6259os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
6260 PyObject *env, PyObject *file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006261 PyObject *setpgroup, int resetids, int setsid,
6262 PyObject *setsigmask, PyObject *setsigdef,
6263 PyObject *scheduler)
6264/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006265{
6266 return py_posix_spawn(1, module, path, argv, env, file_actions,
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03006267 setpgroup, resetids, setsid, setsigmask, setsigdef,
Joannah Nanjekye92b83222019-01-16 16:29:26 +03006268 scheduler);
6269}
6270#endif /* HAVE_POSIX_SPAWNP */
Pablo Galindo6c6ddf92018-01-29 01:56:10 +00006271
pxinwrf2d7ac72019-05-21 18:46:37 +08006272#ifdef HAVE_RTPSPAWN
6273static intptr_t
6274_rtp_spawn(int mode, const char *rtpFileName, const char *argv[],
6275 const char *envp[])
6276{
6277 RTP_ID rtpid;
6278 int status;
6279 pid_t res;
6280 int async_err = 0;
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006281
pxinwrf2d7ac72019-05-21 18:46:37 +08006282 /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes.
6283 uStackSize=0 cannot be used, the default stack size is too small for
6284 Python. */
6285 if (envp) {
6286 rtpid = rtpSpawn(rtpFileName, argv, envp,
6287 100, 0x1000000, 0, VX_FP_TASK);
6288 }
6289 else {
6290 rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ,
6291 100, 0x1000000, 0, VX_FP_TASK);
6292 }
6293 if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) {
6294 do {
6295 res = waitpid((pid_t)rtpid, &status, 0);
6296 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6297
6298 if (res < 0)
6299 return RTP_ID_ERROR;
6300 return ((intptr_t)status);
6301 }
6302 return ((intptr_t)rtpid);
6303}
6304#endif
6305
6306#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)
Larry Hastings2f936352014-08-05 14:04:04 +10006307/*[clinic input]
6308os.spawnv
6309
6310 mode: int
6311 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006312 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006313 Path of executable file.
6314 argv: object
6315 Tuple or list of strings.
6316 /
6317
6318Execute the program specified by path in a new process.
6319[clinic start generated code]*/
6320
Larry Hastings2f936352014-08-05 14:04:04 +10006321static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006322os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
6323/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006324{
Steve Dowercc16be82016-09-08 10:35:16 -07006325 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10006326 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00006327 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006328 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006329 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00006330
Victor Stinner8c62be82010-05-06 00:08:46 +00006331 /* spawnv has three arguments: (mode, path, argv), where
6332 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006333
Victor Stinner8c62be82010-05-06 00:08:46 +00006334 if (PyList_Check(argv)) {
6335 argc = PyList_Size(argv);
6336 getitem = PyList_GetItem;
6337 }
6338 else if (PyTuple_Check(argv)) {
6339 argc = PyTuple_Size(argv);
6340 getitem = PyTuple_GetItem;
6341 }
6342 else {
6343 PyErr_SetString(PyExc_TypeError,
6344 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00006345 return NULL;
6346 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006347 if (argc == 0) {
6348 PyErr_SetString(PyExc_ValueError,
6349 "spawnv() arg 2 cannot be empty");
6350 return NULL;
6351 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006352
Steve Dowercc16be82016-09-08 10:35:16 -07006353 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006354 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 return PyErr_NoMemory();
6356 }
6357 for (i = 0; i < argc; i++) {
6358 if (!fsconvert_strdup((*getitem)(argv, i),
6359 &argvlist[i])) {
6360 free_string_array(argvlist, i);
6361 PyErr_SetString(
6362 PyExc_TypeError,
6363 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 return NULL;
6365 }
Steve Dower93ff8722016-11-19 19:03:54 -08006366 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02006367 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08006368 PyErr_SetString(
6369 PyExc_ValueError,
6370 "spawnv() arg 2 first element cannot be empty");
6371 return NULL;
6372 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006373 }
6374 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006375
pxinwrf2d7ac72019-05-21 18:46:37 +08006376#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006377 if (mode == _OLD_P_OVERLAY)
6378 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006379#endif
Tim Peters5aa91602002-01-30 05:46:57 +00006380
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006381 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv,
Saiyang Gou95f60012020-02-04 16:15:00 -08006382 Py_None) < 0) {
6383 free_string_array(argvlist, argc);
6384 return NULL;
6385 }
6386
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006388 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006389#ifdef HAVE_WSPAWNV
6390 spawnval = _wspawnv(mode, path->wide, argvlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006391#elif defined(HAVE_RTPSPAWN)
6392 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL);
Steve Dowercc16be82016-09-08 10:35:16 -07006393#else
6394 spawnval = _spawnv(mode, path->narrow, argvlist);
6395#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006396 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00006398
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00006400
Victor Stinner8c62be82010-05-06 00:08:46 +00006401 if (spawnval == -1)
6402 return posix_error();
6403 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006404 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006405}
6406
Larry Hastings2f936352014-08-05 14:04:04 +10006407/*[clinic input]
6408os.spawnve
6409
6410 mode: int
6411 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07006412 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10006413 Path of executable file.
6414 argv: object
6415 Tuple or list of strings.
6416 env: object
6417 Dictionary of strings mapping to strings.
6418 /
6419
6420Execute the program specified by path in a new process.
6421[clinic start generated code]*/
6422
Larry Hastings2f936352014-08-05 14:04:04 +10006423static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07006424os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006425 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07006426/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006427{
Steve Dowercc16be82016-09-08 10:35:16 -07006428 EXECV_CHAR **argvlist;
6429 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00006431 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07006432 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00006433 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006434 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00006435
Victor Stinner8c62be82010-05-06 00:08:46 +00006436 /* spawnve has four arguments: (mode, path, argv, env), where
6437 argv is a list or tuple of strings and env is a dictionary
6438 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00006439
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 if (PyList_Check(argv)) {
6441 argc = PyList_Size(argv);
6442 getitem = PyList_GetItem;
6443 }
6444 else if (PyTuple_Check(argv)) {
6445 argc = PyTuple_Size(argv);
6446 getitem = PyTuple_GetItem;
6447 }
6448 else {
6449 PyErr_SetString(PyExc_TypeError,
6450 "spawnve() arg 2 must be a tuple or list");
6451 goto fail_0;
6452 }
Steve Dower859fd7b2016-11-19 18:53:19 -08006453 if (argc == 0) {
6454 PyErr_SetString(PyExc_ValueError,
6455 "spawnve() arg 2 cannot be empty");
6456 goto fail_0;
6457 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006458 if (!PyMapping_Check(env)) {
6459 PyErr_SetString(PyExc_TypeError,
6460 "spawnve() arg 3 must be a mapping object");
6461 goto fail_0;
6462 }
Guido van Rossuma1065681999-01-25 23:20:23 +00006463
Steve Dowercc16be82016-09-08 10:35:16 -07006464 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 if (argvlist == NULL) {
6466 PyErr_NoMemory();
6467 goto fail_0;
6468 }
6469 for (i = 0; i < argc; i++) {
6470 if (!fsconvert_strdup((*getitem)(argv, i),
6471 &argvlist[i]))
6472 {
6473 lastarg = i;
6474 goto fail_1;
6475 }
Steve Dowerbce26262016-11-19 19:17:26 -08006476 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006477 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08006478 PyErr_SetString(
6479 PyExc_ValueError,
6480 "spawnv() arg 2 first element cannot be empty");
6481 goto fail_1;
6482 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006483 }
6484 lastarg = argc;
6485 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00006486
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 envlist = parse_envlist(env, &envc);
6488 if (envlist == NULL)
6489 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00006490
pxinwrf2d7ac72019-05-21 18:46:37 +08006491#if !defined(HAVE_RTPSPAWN)
Victor Stinner8c62be82010-05-06 00:08:46 +00006492 if (mode == _OLD_P_OVERLAY)
6493 mode = _P_OVERLAY;
pxinwrf2d7ac72019-05-21 18:46:37 +08006494#endif
Tim Peters25059d32001-12-07 20:35:43 +00006495
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006496 if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -08006497 goto fail_2;
6498 }
6499
Victor Stinner8c62be82010-05-06 00:08:46 +00006500 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07006501 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07006502#ifdef HAVE_WSPAWNV
6503 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
pxinwrf2d7ac72019-05-21 18:46:37 +08006504#elif defined(HAVE_RTPSPAWN)
6505 spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist,
6506 (const char **)envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07006507#else
6508 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
6509#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07006510 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00006511 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00006512
Victor Stinner8c62be82010-05-06 00:08:46 +00006513 if (spawnval == -1)
6514 (void) posix_error();
6515 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006516 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00006517
Saiyang Gou95f60012020-02-04 16:15:00 -08006518 fail_2:
Victor Stinner00d7abd2020-12-01 09:56:42 +01006519 while (--envc >= 0) {
6520 PyMem_Free(envlist[envc]);
6521 }
6522 PyMem_Free(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00006523 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02006524 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00006525 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00006526 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00006527}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006528
Guido van Rossuma1065681999-01-25 23:20:23 +00006529#endif /* HAVE_SPAWNV */
6530
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006531#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07006532
6533/* Helper function to validate arguments.
6534 Returns 0 on success. non-zero on failure with a TypeError raised.
6535 If obj is non-NULL it must be callable. */
6536static int
6537check_null_or_callable(PyObject *obj, const char* obj_name)
6538{
6539 if (obj && !PyCallable_Check(obj)) {
6540 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
Eddie Elizondob3966632019-11-05 07:16:14 -08006541 obj_name, _PyType_Name(Py_TYPE(obj)));
Gregory P. Smith163468a2017-05-29 10:03:41 -07006542 return -1;
6543 }
6544 return 0;
6545}
6546
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006547/*[clinic input]
6548os.register_at_fork
6549
Gregory P. Smith163468a2017-05-29 10:03:41 -07006550 *
6551 before: object=NULL
6552 A callable to be called in the parent before the fork() syscall.
6553 after_in_child: object=NULL
6554 A callable to be called in the child after fork().
6555 after_in_parent: object=NULL
6556 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006557
Gregory P. Smith163468a2017-05-29 10:03:41 -07006558Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006559
Gregory P. Smith163468a2017-05-29 10:03:41 -07006560'before' callbacks are called in reverse order.
6561'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006562
6563[clinic start generated code]*/
6564
6565static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07006566os_register_at_fork_impl(PyObject *module, PyObject *before,
6567 PyObject *after_in_child, PyObject *after_in_parent)
6568/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006569{
6570 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006571
Gregory P. Smith163468a2017-05-29 10:03:41 -07006572 if (!before && !after_in_child && !after_in_parent) {
6573 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
6574 return NULL;
6575 }
6576 if (check_null_or_callable(before, "before") ||
6577 check_null_or_callable(after_in_child, "after_in_child") ||
6578 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006579 return NULL;
6580 }
Victor Stinner81a7be32020-04-14 15:14:01 +02006581 interp = _PyInterpreterState_GET();
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006582
Gregory P. Smith163468a2017-05-29 10:03:41 -07006583 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006584 return NULL;
6585 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07006586 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006587 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07006588 }
6589 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
6590 return NULL;
6591 }
6592 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006593}
6594#endif /* HAVE_FORK */
6595
6596
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006597#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10006598/*[clinic input]
6599os.fork1
6600
6601Fork a child process with a single multiplexed (i.e., not bound) thread.
6602
6603Return 0 to child process and PID of child to parent process.
6604[clinic start generated code]*/
6605
Larry Hastings2f936352014-08-05 14:04:04 +10006606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006607os_fork1_impl(PyObject *module)
6608/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006609{
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006611
Victor Stinner81a7be32020-04-14 15:14:01 +02006612 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07006613 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
6614 return NULL;
6615 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006616 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 pid = fork1();
6618 if (pid == 0) {
6619 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006620 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006621 } else {
6622 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006623 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006624 }
6625 if (pid == -1)
6626 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006628}
Larry Hastings2f936352014-08-05 14:04:04 +10006629#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006630
6631
Guido van Rossumad0ee831995-03-01 10:34:45 +00006632#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10006633/*[clinic input]
6634os.fork
6635
6636Fork a child process.
6637
6638Return 0 to child process and PID of child to parent process.
6639[clinic start generated code]*/
6640
Larry Hastings2f936352014-08-05 14:04:04 +10006641static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006642os_fork_impl(PyObject *module)
6643/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006644{
Victor Stinner8c62be82010-05-06 00:08:46 +00006645 pid_t pid;
Victor Stinner252346a2020-05-01 11:33:44 +02006646 PyInterpreterState *interp = _PyInterpreterState_GET();
6647 if (interp->config._isolated_interpreter) {
6648 PyErr_SetString(PyExc_RuntimeError,
6649 "fork not supported for isolated subinterpreters");
Eric Snow59032962018-09-14 14:17:20 -07006650 return NULL;
6651 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08006652 if (PySys_Audit("os.fork", NULL) < 0) {
6653 return NULL;
6654 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006655 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006656 pid = fork();
6657 if (pid == 0) {
6658 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006659 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006660 } else {
6661 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006662 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006663 }
6664 if (pid == -1)
6665 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006666 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00006667}
Larry Hastings2f936352014-08-05 14:04:04 +10006668#endif /* HAVE_FORK */
6669
Guido van Rossum85e3b011991-06-03 12:42:10 +00006670
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006671#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006672#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10006673/*[clinic input]
6674os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006675
Larry Hastings2f936352014-08-05 14:04:04 +10006676 policy: int
6677
6678Get the maximum scheduling priority for policy.
6679[clinic start generated code]*/
6680
Larry Hastings2f936352014-08-05 14:04:04 +10006681static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006682os_sched_get_priority_max_impl(PyObject *module, int policy)
6683/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006684{
6685 int max;
6686
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006687 max = sched_get_priority_max(policy);
6688 if (max < 0)
6689 return posix_error();
6690 return PyLong_FromLong(max);
6691}
6692
Larry Hastings2f936352014-08-05 14:04:04 +10006693
6694/*[clinic input]
6695os.sched_get_priority_min
6696
6697 policy: int
6698
6699Get the minimum scheduling priority for policy.
6700[clinic start generated code]*/
6701
Larry Hastings2f936352014-08-05 14:04:04 +10006702static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006703os_sched_get_priority_min_impl(PyObject *module, int policy)
6704/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006705{
6706 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006707 if (min < 0)
6708 return posix_error();
6709 return PyLong_FromLong(min);
6710}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02006711#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
6712
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006713
Larry Hastings2f936352014-08-05 14:04:04 +10006714#ifdef HAVE_SCHED_SETSCHEDULER
6715/*[clinic input]
6716os.sched_getscheduler
6717 pid: pid_t
6718 /
6719
Min ho Kimc4cacc82019-07-31 08:16:13 +10006720Get the scheduling policy for the process identified by pid.
Larry Hastings2f936352014-08-05 14:04:04 +10006721
6722Passing 0 for pid returns the scheduling policy for the calling process.
6723[clinic start generated code]*/
6724
Larry Hastings2f936352014-08-05 14:04:04 +10006725static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006726os_sched_getscheduler_impl(PyObject *module, pid_t pid)
Min ho Kimc4cacc82019-07-31 08:16:13 +10006727/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006728{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006729 int policy;
6730
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006731 policy = sched_getscheduler(pid);
6732 if (policy < 0)
6733 return posix_error();
6734 return PyLong_FromLong(policy);
6735}
Larry Hastings2f936352014-08-05 14:04:04 +10006736#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006737
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006738
William Orr81574b82018-10-01 22:19:56 -07006739#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10006740/*[clinic input]
Eddie Elizondo474eedf2018-11-13 04:09:31 -08006741class os.sched_param "PyObject *" "SchedParamType"
Larry Hastings2f936352014-08-05 14:04:04 +10006742
6743@classmethod
6744os.sched_param.__new__
6745
6746 sched_priority: object
6747 A scheduling parameter.
6748
Eddie Elizondob3966632019-11-05 07:16:14 -08006749Currently has only one field: sched_priority
Larry Hastings2f936352014-08-05 14:04:04 +10006750[clinic start generated code]*/
6751
Larry Hastings2f936352014-08-05 14:04:04 +10006752static PyObject *
6753os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Eddie Elizondob3966632019-11-05 07:16:14 -08006754/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006755{
6756 PyObject *res;
6757
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006758 res = PyStructSequence_New(type);
6759 if (!res)
6760 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10006761 Py_INCREF(sched_priority);
6762 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006763 return res;
6764}
6765
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006766PyDoc_VAR(os_sched_param__doc__);
6767
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006768static PyStructSequence_Field sched_param_fields[] = {
6769 {"sched_priority", "the scheduling priority"},
6770 {0}
6771};
6772
6773static PyStructSequence_Desc sched_param_desc = {
6774 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10006775 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006776 sched_param_fields,
6777 1
6778};
6779
6780static int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006781convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006782{
6783 long priority;
6784
Victor Stinner1c2fa782020-05-10 11:05:29 +02006785 if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) {
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006786 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
6787 return 0;
6788 }
6789 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
6790 if (priority == -1 && PyErr_Occurred())
6791 return 0;
6792 if (priority > INT_MAX || priority < INT_MIN) {
6793 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
6794 return 0;
6795 }
6796 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
6797 return 1;
6798}
William Orr81574b82018-10-01 22:19:56 -07006799#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006800
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006801
6802#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10006803/*[clinic input]
6804os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006805
Larry Hastings2f936352014-08-05 14:04:04 +10006806 pid: pid_t
6807 policy: int
Victor Stinner1c2fa782020-05-10 11:05:29 +02006808 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006809 /
6810
6811Set the scheduling policy for the process identified by pid.
6812
6813If pid is 0, the calling process is changed.
6814param is an instance of sched_param.
6815[clinic start generated code]*/
6816
Larry Hastings2f936352014-08-05 14:04:04 +10006817static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006818os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Victor Stinner1c2fa782020-05-10 11:05:29 +02006819 PyObject *param_obj)
6820/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006821{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006822 struct sched_param param;
6823 if (!convert_sched_param(module, param_obj, &param)) {
6824 return NULL;
6825 }
6826
Jesus Cea9c822272011-09-10 01:40:52 +02006827 /*
Jesus Cea54b01492011-09-10 01:53:19 +02006828 ** sched_setscheduler() returns 0 in Linux, but the previous
6829 ** scheduling policy under Solaris/Illumos, and others.
6830 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02006831 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02006832 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006833 return posix_error();
6834 Py_RETURN_NONE;
6835}
Larry Hastings2f936352014-08-05 14:04:04 +10006836#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006837
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006838
6839#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10006840/*[clinic input]
6841os.sched_getparam
6842 pid: pid_t
6843 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006844
Larry Hastings2f936352014-08-05 14:04:04 +10006845Returns scheduling parameters for the process identified by pid.
6846
6847If pid is 0, returns parameters for the calling process.
6848Return value is an instance of sched_param.
6849[clinic start generated code]*/
6850
Larry Hastings2f936352014-08-05 14:04:04 +10006851static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006852os_sched_getparam_impl(PyObject *module, pid_t pid)
6853/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006854{
6855 struct sched_param param;
6856 PyObject *result;
6857 PyObject *priority;
6858
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006859 if (sched_getparam(pid, &param))
6860 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02006861 PyObject *SchedParamType = get_posix_state(module)->SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -08006862 result = PyStructSequence_New((PyTypeObject *)SchedParamType);
Larry Hastings2f936352014-08-05 14:04:04 +10006863 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006864 return NULL;
6865 priority = PyLong_FromLong(param.sched_priority);
6866 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10006867 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006868 return NULL;
6869 }
Larry Hastings2f936352014-08-05 14:04:04 +10006870 PyStructSequence_SET_ITEM(result, 0, priority);
6871 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006872}
6873
Larry Hastings2f936352014-08-05 14:04:04 +10006874
6875/*[clinic input]
6876os.sched_setparam
6877 pid: pid_t
Victor Stinner1c2fa782020-05-10 11:05:29 +02006878 param as param_obj: object
Larry Hastings2f936352014-08-05 14:04:04 +10006879 /
6880
6881Set scheduling parameters for the process identified by pid.
6882
6883If pid is 0, sets parameters for the calling process.
6884param should be an instance of sched_param.
6885[clinic start generated code]*/
6886
Larry Hastings2f936352014-08-05 14:04:04 +10006887static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02006888os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj)
6889/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006890{
Victor Stinner1c2fa782020-05-10 11:05:29 +02006891 struct sched_param param;
6892 if (!convert_sched_param(module, param_obj, &param)) {
6893 return NULL;
6894 }
6895
6896 if (sched_setparam(pid, &param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006897 return posix_error();
6898 Py_RETURN_NONE;
6899}
Larry Hastings2f936352014-08-05 14:04:04 +10006900#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006901
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006902
6903#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10006904/*[clinic input]
6905os.sched_rr_get_interval -> double
6906 pid: pid_t
6907 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006908
Larry Hastings2f936352014-08-05 14:04:04 +10006909Return the round-robin quantum for the process identified by pid, in seconds.
6910
6911Value returned is a float.
6912[clinic start generated code]*/
6913
Larry Hastings2f936352014-08-05 14:04:04 +10006914static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006915os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
6916/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006917{
6918 struct timespec interval;
6919 if (sched_rr_get_interval(pid, &interval)) {
6920 posix_error();
6921 return -1.0;
6922 }
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08006923#ifdef _Py_MEMORY_SANITIZER
6924 __msan_unpoison(&interval, sizeof(interval));
6925#endif
Larry Hastings2f936352014-08-05 14:04:04 +10006926 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
6927}
6928#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05006929
Larry Hastings2f936352014-08-05 14:04:04 +10006930
6931/*[clinic input]
6932os.sched_yield
6933
6934Voluntarily relinquish the CPU.
6935[clinic start generated code]*/
6936
Larry Hastings2f936352014-08-05 14:04:04 +10006937static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006938os_sched_yield_impl(PyObject *module)
6939/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006940{
6941 if (sched_yield())
6942 return posix_error();
6943 Py_RETURN_NONE;
6944}
6945
Benjamin Peterson2740af82011-08-02 17:41:34 -05006946#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02006947/* The minimum number of CPUs allocated in a cpu_set_t */
6948static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006949
Larry Hastings2f936352014-08-05 14:04:04 +10006950/*[clinic input]
6951os.sched_setaffinity
6952 pid: pid_t
6953 mask : object
6954 /
6955
6956Set the CPU affinity of the process identified by pid to mask.
6957
6958mask should be an iterable of integers identifying CPUs.
6959[clinic start generated code]*/
6960
Larry Hastings2f936352014-08-05 14:04:04 +10006961static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006962os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
6963/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006964{
Antoine Pitrou84869872012-08-04 16:16:35 +02006965 int ncpus;
6966 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10006967 cpu_set_t *cpu_set = NULL;
6968 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006969
Larry Hastings2f936352014-08-05 14:04:04 +10006970 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02006971 if (iterator == NULL)
6972 return NULL;
6973
6974 ncpus = NCPUS_START;
6975 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10006976 cpu_set = CPU_ALLOC(ncpus);
6977 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02006978 PyErr_NoMemory();
6979 goto error;
6980 }
Larry Hastings2f936352014-08-05 14:04:04 +10006981 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02006982
6983 while ((item = PyIter_Next(iterator))) {
6984 long cpu;
6985 if (!PyLong_Check(item)) {
6986 PyErr_Format(PyExc_TypeError,
6987 "expected an iterator of ints, "
6988 "but iterator yielded %R",
6989 Py_TYPE(item));
6990 Py_DECREF(item);
6991 goto error;
6992 }
6993 cpu = PyLong_AsLong(item);
6994 Py_DECREF(item);
6995 if (cpu < 0) {
6996 if (!PyErr_Occurred())
6997 PyErr_SetString(PyExc_ValueError, "negative CPU number");
6998 goto error;
6999 }
7000 if (cpu > INT_MAX - 1) {
7001 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
7002 goto error;
7003 }
7004 if (cpu >= ncpus) {
7005 /* Grow CPU mask to fit the CPU number */
7006 int newncpus = ncpus;
7007 cpu_set_t *newmask;
7008 size_t newsetsize;
7009 while (newncpus <= cpu) {
7010 if (newncpus > INT_MAX / 2)
7011 newncpus = cpu + 1;
7012 else
7013 newncpus = newncpus * 2;
7014 }
7015 newmask = CPU_ALLOC(newncpus);
7016 if (newmask == NULL) {
7017 PyErr_NoMemory();
7018 goto error;
7019 }
7020 newsetsize = CPU_ALLOC_SIZE(newncpus);
7021 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10007022 memcpy(newmask, cpu_set, setsize);
7023 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007024 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10007025 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02007026 ncpus = newncpus;
7027 }
Larry Hastings2f936352014-08-05 14:04:04 +10007028 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007029 }
Brandt Bucher45a30af2019-06-27 09:10:57 -07007030 if (PyErr_Occurred()) {
7031 goto error;
7032 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007033 Py_CLEAR(iterator);
7034
Larry Hastings2f936352014-08-05 14:04:04 +10007035 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02007036 posix_error();
7037 goto error;
7038 }
Larry Hastings2f936352014-08-05 14:04:04 +10007039 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007040 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02007041
7042error:
Larry Hastings2f936352014-08-05 14:04:04 +10007043 if (cpu_set)
7044 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02007045 Py_XDECREF(iterator);
7046 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007047}
7048
Larry Hastings2f936352014-08-05 14:04:04 +10007049
7050/*[clinic input]
7051os.sched_getaffinity
7052 pid: pid_t
7053 /
7054
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01007055Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10007056
7057The affinity is returned as a set of CPU identifiers.
7058[clinic start generated code]*/
7059
Larry Hastings2f936352014-08-05 14:04:04 +10007060static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007061os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03007062/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007063{
Antoine Pitrou84869872012-08-04 16:16:35 +02007064 int cpu, ncpus, count;
7065 size_t setsize;
7066 cpu_set_t *mask = NULL;
7067 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007068
Antoine Pitrou84869872012-08-04 16:16:35 +02007069 ncpus = NCPUS_START;
7070 while (1) {
7071 setsize = CPU_ALLOC_SIZE(ncpus);
7072 mask = CPU_ALLOC(ncpus);
7073 if (mask == NULL)
7074 return PyErr_NoMemory();
7075 if (sched_getaffinity(pid, setsize, mask) == 0)
7076 break;
7077 CPU_FREE(mask);
7078 if (errno != EINVAL)
7079 return posix_error();
7080 if (ncpus > INT_MAX / 2) {
7081 PyErr_SetString(PyExc_OverflowError, "could not allocate "
7082 "a large enough CPU set");
7083 return NULL;
7084 }
7085 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007086 }
Antoine Pitrou84869872012-08-04 16:16:35 +02007087
7088 res = PySet_New(NULL);
7089 if (res == NULL)
7090 goto error;
7091 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
7092 if (CPU_ISSET_S(cpu, setsize, mask)) {
7093 PyObject *cpu_num = PyLong_FromLong(cpu);
7094 --count;
7095 if (cpu_num == NULL)
7096 goto error;
7097 if (PySet_Add(res, cpu_num)) {
7098 Py_DECREF(cpu_num);
7099 goto error;
7100 }
7101 Py_DECREF(cpu_num);
7102 }
7103 }
7104 CPU_FREE(mask);
7105 return res;
7106
7107error:
7108 if (mask)
7109 CPU_FREE(mask);
7110 Py_XDECREF(res);
7111 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007112}
7113
Benjamin Peterson2740af82011-08-02 17:41:34 -05007114#endif /* HAVE_SCHED_SETAFFINITY */
7115
Benjamin Peterson94b580d2011-08-02 17:30:04 -05007116#endif /* HAVE_SCHED_H */
7117
Larry Hastings2f936352014-08-05 14:04:04 +10007118
Neal Norwitzb59798b2003-03-21 01:43:31 +00007119/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00007120#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Victor Stinner57766632020-10-29 15:16:23 +01007121# define DEV_PTY_FILE "/dev/ptc"
7122# define HAVE_DEV_PTMX
Neal Norwitzb59798b2003-03-21 01:43:31 +00007123#else
Victor Stinner57766632020-10-29 15:16:23 +01007124# define DEV_PTY_FILE "/dev/ptmx"
Neal Norwitzb59798b2003-03-21 01:43:31 +00007125#endif
7126
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007127#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00007128#ifdef HAVE_PTY_H
7129#include <pty.h>
7130#else
7131#ifdef HAVE_LIBUTIL_H
7132#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00007133#else
7134#ifdef HAVE_UTIL_H
7135#include <util.h>
7136#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007137#endif /* HAVE_LIBUTIL_H */
7138#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00007139#ifdef HAVE_STROPTS_H
7140#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007141#endif
ngie-eign7745ec42018-02-14 11:54:28 -08007142#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007143
Larry Hastings2f936352014-08-05 14:04:04 +10007144
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007145#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10007146/*[clinic input]
7147os.openpty
7148
7149Open a pseudo-terminal.
7150
7151Return a tuple of (master_fd, slave_fd) containing open file descriptors
7152for both the master and slave ends.
7153[clinic start generated code]*/
7154
Larry Hastings2f936352014-08-05 14:04:04 +10007155static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007156os_openpty_impl(PyObject *module)
7157/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007158{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007159 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007160#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007161 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007162#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007163#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007164 PyOS_sighandler_t sig_saved;
Jakub Kulík6f9bc722018-12-31 03:16:40 +01007165#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00007166 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007167#endif
7168#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00007169
Thomas Wouters70c21a12000-07-14 14:28:33 +00007170#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007171 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007172 goto posix_error;
7173
7174 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7175 goto error;
7176 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
7177 goto error;
7178
Neal Norwitzb59798b2003-03-21 01:43:31 +00007179#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
7181 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007182 goto posix_error;
7183 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7184 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00007185
Victor Stinnerdaf45552013-08-28 00:53:59 +02007186 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00007187 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01007188 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007189
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007190#else
Victor Stinner000de532013-11-25 23:19:58 +01007191 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00007192 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007193 goto posix_error;
7194
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007196
Victor Stinner8c62be82010-05-06 00:08:46 +00007197 /* change permission of slave */
7198 if (grantpt(master_fd) < 0) {
7199 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007200 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007201 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007202
Victor Stinner8c62be82010-05-06 00:08:46 +00007203 /* unlock slave */
7204 if (unlockpt(master_fd) < 0) {
7205 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007206 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007207 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007208
Victor Stinner8c62be82010-05-06 00:08:46 +00007209 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02007210
Victor Stinner8c62be82010-05-06 00:08:46 +00007211 slave_name = ptsname(master_fd); /* get name of slave */
7212 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02007213 goto posix_error;
7214
7215 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01007216 if (slave_fd == -1)
7217 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01007218
7219 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
7220 goto posix_error;
7221
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02007222#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00007223 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
7224 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00007225#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00007226 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00007227#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007228#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00007229#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00007230
Victor Stinner8c62be82010-05-06 00:08:46 +00007231 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00007232
Victor Stinnerdaf45552013-08-28 00:53:59 +02007233posix_error:
7234 posix_error();
7235error:
7236 if (master_fd != -1)
7237 close(master_fd);
7238 if (slave_fd != -1)
7239 close(slave_fd);
7240 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00007241}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007242#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007243
Larry Hastings2f936352014-08-05 14:04:04 +10007244
Fred Drake8cef4cf2000-06-28 16:40:38 +00007245#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10007246/*[clinic input]
7247os.forkpty
7248
7249Fork a new process with a new pseudo-terminal as controlling tty.
7250
7251Returns a tuple of (pid, master_fd).
7252Like fork(), return pid of 0 to the child process,
7253and pid of child to the parent process.
7254To both, return fd of newly opened pseudo-terminal.
7255[clinic start generated code]*/
7256
Larry Hastings2f936352014-08-05 14:04:04 +10007257static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007258os_forkpty_impl(PyObject *module)
7259/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00007260{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007261 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00007262 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00007263
Victor Stinner81a7be32020-04-14 15:14:01 +02007264 if (_PyInterpreterState_GET() != PyInterpreterState_Main()) {
Eric Snow59032962018-09-14 14:17:20 -07007265 PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters");
7266 return NULL;
7267 }
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007268 if (PySys_Audit("os.forkpty", NULL) < 0) {
7269 return NULL;
7270 }
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007271 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00007272 pid = forkpty(&master_fd, NULL, NULL, NULL);
7273 if (pid == 0) {
7274 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007275 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00007276 } else {
7277 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007278 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00007279 }
7280 if (pid == -1)
7281 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007282 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00007283}
Larry Hastings2f936352014-08-05 14:04:04 +10007284#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007285
Ross Lagerwall7807c352011-03-17 20:20:30 +02007286
Guido van Rossumad0ee831995-03-01 10:34:45 +00007287#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007288/*[clinic input]
7289os.getegid
7290
7291Return the current process's effective group id.
7292[clinic start generated code]*/
7293
Larry Hastings2f936352014-08-05 14:04:04 +10007294static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007295os_getegid_impl(PyObject *module)
7296/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007297{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007298 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007299}
Larry Hastings2f936352014-08-05 14:04:04 +10007300#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007301
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007302
Guido van Rossumad0ee831995-03-01 10:34:45 +00007303#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007304/*[clinic input]
7305os.geteuid
7306
7307Return the current process's effective user id.
7308[clinic start generated code]*/
7309
Larry Hastings2f936352014-08-05 14:04:04 +10007310static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007311os_geteuid_impl(PyObject *module)
7312/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007313{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007314 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007315}
Larry Hastings2f936352014-08-05 14:04:04 +10007316#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007317
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007318
Guido van Rossumad0ee831995-03-01 10:34:45 +00007319#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10007320/*[clinic input]
7321os.getgid
7322
7323Return the current process's group id.
7324[clinic start generated code]*/
7325
Larry Hastings2f936352014-08-05 14:04:04 +10007326static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007327os_getgid_impl(PyObject *module)
7328/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007329{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007330 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007331}
Larry Hastings2f936352014-08-05 14:04:04 +10007332#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007334
Berker Peksag39404992016-09-15 20:45:16 +03007335#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10007336/*[clinic input]
7337os.getpid
7338
7339Return the current process id.
7340[clinic start generated code]*/
7341
Larry Hastings2f936352014-08-05 14:04:04 +10007342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007343os_getpid_impl(PyObject *module)
7344/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007345{
Victor Stinner8c62be82010-05-06 00:08:46 +00007346 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00007347}
Berker Peksag39404992016-09-15 20:45:16 +03007348#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007349
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007350#ifdef NGROUPS_MAX
7351#define MAX_GROUPS NGROUPS_MAX
7352#else
7353 /* defined to be 16 on Solaris7, so this should be a small number */
7354#define MAX_GROUPS 64
7355#endif
7356
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007357#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10007358
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007359#ifdef __APPLE__
7360/*[clinic input]
7361os.getgrouplist
7362
7363 user: str
7364 username to lookup
7365 group as basegid: int
7366 base group id of the user
7367 /
7368
7369Returns a list of groups to which a user belongs.
7370[clinic start generated code]*/
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007371
7372static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007373os_getgrouplist_impl(PyObject *module, const char *user, int basegid)
7374/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/
7375#else
7376/*[clinic input]
7377os.getgrouplist
7378
7379 user: str
7380 username to lookup
7381 group as basegid: gid_t
7382 base group id of the user
7383 /
7384
7385Returns a list of groups to which a user belongs.
7386[clinic start generated code]*/
7387
7388static PyObject *
7389os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid)
7390/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/
7391#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007392{
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007393 int i, ngroups;
7394 PyObject *list;
7395#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007396 int *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007397#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007398 gid_t *groups;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007399#endif
Jeffrey Kintscher8725c832019-06-13 00:01:29 -07007400
7401 /*
7402 * NGROUPS_MAX is defined by POSIX.1 as the maximum
7403 * number of supplimental groups a users can belong to.
7404 * We have to increment it by one because
7405 * getgrouplist() returns both the supplemental groups
7406 * and the primary group, i.e. all of the groups the
7407 * user belongs to.
7408 */
7409 ngroups = 1 + MAX_GROUPS;
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007410
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007411 while (1) {
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007412#ifdef __APPLE__
Victor Stinner8ec73702020-03-23 20:00:57 +01007413 groups = PyMem_New(int, ngroups);
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007414#else
7415 groups = PyMem_New(gid_t, ngroups);
7416#endif
Victor Stinner8ec73702020-03-23 20:00:57 +01007417 if (groups == NULL) {
7418 return PyErr_NoMemory();
7419 }
Victor Stinnerf5c7cab2020-03-24 18:22:10 +01007420
7421 int old_ngroups = ngroups;
7422 if (getgrouplist(user, basegid, groups, &ngroups) != -1) {
7423 /* Success */
7424 break;
7425 }
7426
7427 /* getgrouplist() fails if the group list is too small */
7428 PyMem_Free(groups);
7429
7430 if (ngroups > old_ngroups) {
7431 /* If the group list is too small, the glibc implementation of
7432 getgrouplist() sets ngroups to the total number of groups and
7433 returns -1. */
7434 }
7435 else {
7436 /* Double the group list size */
7437 if (ngroups > INT_MAX / 2) {
7438 return PyErr_NoMemory();
7439 }
7440 ngroups *= 2;
7441 }
7442
7443 /* Retry getgrouplist() with a larger group list */
Victor Stinner8ec73702020-03-23 20:00:57 +01007444 }
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007445
Gregory P. Smith1d300ce2018-12-30 21:13:02 -08007446#ifdef _Py_MEMORY_SANITIZER
7447 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
7448 __msan_unpoison(&ngroups, sizeof(ngroups));
7449 __msan_unpoison(groups, ngroups*sizeof(*groups));
7450#endif
7451
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007452 list = PyList_New(ngroups);
7453 if (list == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01007454 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007455 return NULL;
7456 }
7457
7458 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007459#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007460 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007461#else
7462 PyObject *o = _PyLong_FromGid(groups[i]);
7463#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007464 if (o == NULL) {
7465 Py_DECREF(list);
Victor Stinner00d7abd2020-12-01 09:56:42 +01007466 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007467 return NULL;
7468 }
7469 PyList_SET_ITEM(list, i, o);
7470 }
7471
Victor Stinner00d7abd2020-12-01 09:56:42 +01007472 PyMem_Free(groups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02007473
7474 return list;
7475}
Larry Hastings2f936352014-08-05 14:04:04 +10007476#endif /* HAVE_GETGROUPLIST */
7477
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007478
Fred Drakec9680921999-12-13 16:37:25 +00007479#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10007480/*[clinic input]
7481os.getgroups
7482
7483Return list of supplemental group IDs for the process.
7484[clinic start generated code]*/
7485
Larry Hastings2f936352014-08-05 14:04:04 +10007486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007487os_getgroups_impl(PyObject *module)
7488/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00007489{
7490 PyObject *result = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007491 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007492
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007493 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007494 * This is a helper variable to store the intermediate result when
7495 * that happens.
7496 *
7497 * To keep the code readable the OSX behaviour is unconditional,
7498 * according to the POSIX spec this should be safe on all unix-y
7499 * systems.
7500 */
7501 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00007502 int n;
Fred Drakec9680921999-12-13 16:37:25 +00007503
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007504#ifdef __APPLE__
7505 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
7506 * there are more groups than can fit in grouplist. Therefore, on OS X
7507 * always first call getgroups with length 0 to get the actual number
7508 * of groups.
7509 */
7510 n = getgroups(0, NULL);
7511 if (n < 0) {
7512 return posix_error();
7513 } else if (n <= MAX_GROUPS) {
7514 /* groups will fit in existing array */
7515 alt_grouplist = grouplist;
7516 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007517 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007518 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007519 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007520 }
7521 }
7522
7523 n = getgroups(n, alt_grouplist);
7524 if (n == -1) {
7525 if (alt_grouplist != grouplist) {
7526 PyMem_Free(alt_grouplist);
7527 }
7528 return posix_error();
7529 }
7530#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007531 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007532 if (n < 0) {
7533 if (errno == EINVAL) {
7534 n = getgroups(0, NULL);
7535 if (n == -1) {
7536 return posix_error();
7537 }
7538 if (n == 0) {
7539 /* Avoid malloc(0) */
7540 alt_grouplist = grouplist;
7541 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02007542 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007543 if (alt_grouplist == NULL) {
Zackery Spytz4c49da02018-12-07 03:11:30 -07007544 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007545 }
7546 n = getgroups(n, alt_grouplist);
7547 if (n == -1) {
7548 PyMem_Free(alt_grouplist);
7549 return posix_error();
7550 }
7551 }
7552 } else {
7553 return posix_error();
7554 }
7555 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07007556#endif
7557
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007558 result = PyList_New(n);
7559 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007560 int i;
7561 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007562 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00007563 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007564 Py_DECREF(result);
7565 result = NULL;
7566 break;
Fred Drakec9680921999-12-13 16:37:25 +00007567 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007568 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00007569 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00007570 }
7571
7572 if (alt_grouplist != grouplist) {
7573 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00007574 }
Neal Norwitze241ce82003-02-17 18:17:05 +00007575
Fred Drakec9680921999-12-13 16:37:25 +00007576 return result;
7577}
Larry Hastings2f936352014-08-05 14:04:04 +10007578#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00007579
Antoine Pitroub7572f02009-12-02 20:46:48 +00007580#ifdef HAVE_INITGROUPS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007581#ifdef __APPLE__
7582/*[clinic input]
7583os.initgroups
Antoine Pitroub7572f02009-12-02 20:46:48 +00007584
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007585 username as oname: FSConverter
7586 gid: int
7587 /
7588
7589Initialize the group access list.
7590
7591Call the system initgroups() to initialize the group access list with all of
7592the groups of which the specified username is a member, plus the specified
7593group id.
7594[clinic start generated code]*/
7595
Antoine Pitroub7572f02009-12-02 20:46:48 +00007596static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007597os_initgroups_impl(PyObject *module, PyObject *oname, int gid)
7598/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/
7599#else
7600/*[clinic input]
7601os.initgroups
7602
7603 username as oname: FSConverter
7604 gid: gid_t
7605 /
7606
7607Initialize the group access list.
7608
7609Call the system initgroups() to initialize the group access list with all of
7610the groups of which the specified username is a member, plus the specified
7611group id.
7612[clinic start generated code]*/
7613
7614static PyObject *
7615os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid)
7616/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/
7617#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00007618{
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007619 const char *username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007620
Serhiy Storchaka2b560312020-04-18 19:14:10 +03007621 if (initgroups(username, gid) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00007622 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00007623
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007624 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00007625}
Larry Hastings2f936352014-08-05 14:04:04 +10007626#endif /* HAVE_INITGROUPS */
7627
Antoine Pitroub7572f02009-12-02 20:46:48 +00007628
Martin v. Löwis606edc12002-06-13 21:09:11 +00007629#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007630/*[clinic input]
7631os.getpgid
7632
7633 pid: pid_t
7634
7635Call the system call getpgid(), and return the result.
7636[clinic start generated code]*/
7637
Larry Hastings2f936352014-08-05 14:04:04 +10007638static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007639os_getpgid_impl(PyObject *module, pid_t pid)
7640/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007641{
7642 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 if (pgid < 0)
7644 return posix_error();
7645 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00007646}
7647#endif /* HAVE_GETPGID */
7648
7649
Guido van Rossumb6775db1994-08-01 11:34:53 +00007650#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007651/*[clinic input]
7652os.getpgrp
7653
7654Return the current process group id.
7655[clinic start generated code]*/
7656
Larry Hastings2f936352014-08-05 14:04:04 +10007657static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007658os_getpgrp_impl(PyObject *module)
7659/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00007660{
Guido van Rossumb6775db1994-08-01 11:34:53 +00007661#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007662 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007663#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007664 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007665#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00007666}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007667#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00007668
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007669
Guido van Rossumb6775db1994-08-01 11:34:53 +00007670#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007671/*[clinic input]
7672os.setpgrp
7673
7674Make the current process the leader of its process group.
7675[clinic start generated code]*/
7676
Larry Hastings2f936352014-08-05 14:04:04 +10007677static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007678os_setpgrp_impl(PyObject *module)
7679/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007680{
Guido van Rossum64933891994-10-20 21:56:42 +00007681#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00007682 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007683#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007684 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00007685#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02007687 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007688}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007689#endif /* HAVE_SETPGRP */
7690
Guido van Rossumad0ee831995-03-01 10:34:45 +00007691#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007692
7693#ifdef MS_WINDOWS
7694#include <tlhelp32.h>
7695
7696static PyObject*
7697win32_getppid()
7698{
7699 HANDLE snapshot;
7700 pid_t mypid;
7701 PyObject* result = NULL;
7702 BOOL have_record;
7703 PROCESSENTRY32 pe;
7704
7705 mypid = getpid(); /* This function never fails */
7706
7707 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
7708 if (snapshot == INVALID_HANDLE_VALUE)
7709 return PyErr_SetFromWindowsErr(GetLastError());
7710
7711 pe.dwSize = sizeof(pe);
7712 have_record = Process32First(snapshot, &pe);
7713 while (have_record) {
7714 if (mypid == (pid_t)pe.th32ProcessID) {
7715 /* We could cache the ulong value in a static variable. */
7716 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
7717 break;
7718 }
7719
7720 have_record = Process32Next(snapshot, &pe);
7721 }
7722
7723 /* If our loop exits and our pid was not found (result will be NULL)
7724 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
7725 * error anyway, so let's raise it. */
7726 if (!result)
7727 result = PyErr_SetFromWindowsErr(GetLastError());
7728
7729 CloseHandle(snapshot);
7730
7731 return result;
7732}
7733#endif /*MS_WINDOWS*/
7734
Larry Hastings2f936352014-08-05 14:04:04 +10007735
7736/*[clinic input]
7737os.getppid
7738
7739Return the parent's process id.
7740
7741If the parent process has already exited, Windows machines will still
7742return its id; others systems will return the id of the 'init' process (1).
7743[clinic start generated code]*/
7744
Larry Hastings2f936352014-08-05 14:04:04 +10007745static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007746os_getppid_impl(PyObject *module)
7747/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00007748{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007749#ifdef MS_WINDOWS
7750 return win32_getppid();
7751#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00007753#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00007754}
7755#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007756
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007757
Fred Drake12c6e2d1999-12-14 21:25:03 +00007758#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10007759/*[clinic input]
7760os.getlogin
7761
7762Return the actual login name.
7763[clinic start generated code]*/
7764
Larry Hastings2f936352014-08-05 14:04:04 +10007765static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007766os_getlogin_impl(PyObject *module)
7767/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00007768{
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007770#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007771 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02007772 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007773
7774 if (GetUserNameW(user_name, &num_chars)) {
7775 /* num_chars is the number of unicode chars plus null terminator */
7776 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007777 }
7778 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007779 result = PyErr_SetFromWindowsErr(GetLastError());
7780#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007781 char *name;
7782 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007783
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 errno = 0;
7785 name = getlogin();
7786 if (name == NULL) {
7787 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00007788 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00007789 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007790 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 }
7792 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00007793 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007795#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00007796 return result;
7797}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00007798#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007799
Larry Hastings2f936352014-08-05 14:04:04 +10007800
Guido van Rossumad0ee831995-03-01 10:34:45 +00007801#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007802/*[clinic input]
7803os.getuid
7804
7805Return the current process's user id.
7806[clinic start generated code]*/
7807
Larry Hastings2f936352014-08-05 14:04:04 +10007808static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007809os_getuid_impl(PyObject *module)
7810/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00007811{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007812 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00007813}
Larry Hastings2f936352014-08-05 14:04:04 +10007814#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00007815
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007816
Brian Curtineb24d742010-04-12 17:16:38 +00007817#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007818#define HAVE_KILL
7819#endif /* MS_WINDOWS */
7820
7821#ifdef HAVE_KILL
7822/*[clinic input]
7823os.kill
7824
7825 pid: pid_t
7826 signal: Py_ssize_t
7827 /
7828
7829Kill a process with a signal.
7830[clinic start generated code]*/
7831
Larry Hastings2f936352014-08-05 14:04:04 +10007832static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007833os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
7834/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007835{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007836 if (PySys_Audit("os.kill", "in", pid, signal) < 0) {
7837 return NULL;
7838 }
7839#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007840 if (kill(pid, (int)signal) == -1)
7841 return posix_error();
7842 Py_RETURN_NONE;
Larry Hastings2f936352014-08-05 14:04:04 +10007843#else /* !MS_WINDOWS */
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00007844 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10007845 DWORD sig = (DWORD)signal;
7846 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00007848
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 /* Console processes which share a common console can be sent CTRL+C or
7850 CTRL+BREAK events, provided they handle said events. */
7851 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007852 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007853 err = GetLastError();
7854 PyErr_SetFromWindowsErr(err);
7855 }
7856 else
7857 Py_RETURN_NONE;
7858 }
Brian Curtineb24d742010-04-12 17:16:38 +00007859
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
7861 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01007862 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00007863 if (handle == NULL) {
7864 err = GetLastError();
7865 return PyErr_SetFromWindowsErr(err);
7866 }
Brian Curtineb24d742010-04-12 17:16:38 +00007867
Victor Stinner8c62be82010-05-06 00:08:46 +00007868 if (TerminateProcess(handle, sig) == 0) {
7869 err = GetLastError();
7870 result = PyErr_SetFromWindowsErr(err);
7871 } else {
7872 Py_INCREF(Py_None);
7873 result = Py_None;
7874 }
Brian Curtineb24d742010-04-12 17:16:38 +00007875
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 CloseHandle(handle);
7877 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10007878#endif /* !MS_WINDOWS */
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007879}
Larry Hastings2f936352014-08-05 14:04:04 +10007880#endif /* HAVE_KILL */
7881
7882
7883#ifdef HAVE_KILLPG
7884/*[clinic input]
7885os.killpg
7886
7887 pgid: pid_t
7888 signal: int
7889 /
7890
7891Kill a process group with a signal.
7892[clinic start generated code]*/
7893
Larry Hastings2f936352014-08-05 14:04:04 +10007894static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007895os_killpg_impl(PyObject *module, pid_t pgid, int signal)
7896/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007897{
Saiyang Gou7514f4f2020-02-12 23:47:42 -08007898 if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) {
7899 return NULL;
7900 }
Larry Hastings2f936352014-08-05 14:04:04 +10007901 /* XXX some man pages make the `pgid` parameter an int, others
7902 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
7903 take the same type. Moreover, pid_t is always at least as wide as
7904 int (else compilation of this module fails), which is safe. */
7905 if (killpg(pgid, signal) == -1)
7906 return posix_error();
7907 Py_RETURN_NONE;
7908}
7909#endif /* HAVE_KILLPG */
7910
Brian Curtineb24d742010-04-12 17:16:38 +00007911
Guido van Rossumc0125471996-06-28 18:55:32 +00007912#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00007913#ifdef HAVE_SYS_LOCK_H
7914#include <sys/lock.h>
7915#endif
7916
Larry Hastings2f936352014-08-05 14:04:04 +10007917/*[clinic input]
7918os.plock
7919 op: int
7920 /
7921
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007922Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10007923[clinic start generated code]*/
7924
Larry Hastings2f936352014-08-05 14:04:04 +10007925static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007926os_plock_impl(PyObject *module, int op)
7927/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007928{
Victor Stinner8c62be82010-05-06 00:08:46 +00007929 if (plock(op) == -1)
7930 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007931 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00007932}
Larry Hastings2f936352014-08-05 14:04:04 +10007933#endif /* HAVE_PLOCK */
7934
Guido van Rossumc0125471996-06-28 18:55:32 +00007935
Guido van Rossumb6775db1994-08-01 11:34:53 +00007936#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10007937/*[clinic input]
7938os.setuid
7939
7940 uid: uid_t
7941 /
7942
7943Set the current process's user id.
7944[clinic start generated code]*/
7945
Larry Hastings2f936352014-08-05 14:04:04 +10007946static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007947os_setuid_impl(PyObject *module, uid_t uid)
7948/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007949{
Victor Stinner8c62be82010-05-06 00:08:46 +00007950 if (setuid(uid) < 0)
7951 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007952 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007953}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007954#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00007955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007956
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007957#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10007958/*[clinic input]
7959os.seteuid
7960
7961 euid: uid_t
7962 /
7963
7964Set the current process's effective user id.
7965[clinic start generated code]*/
7966
Larry Hastings2f936352014-08-05 14:04:04 +10007967static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007968os_seteuid_impl(PyObject *module, uid_t euid)
7969/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007970{
7971 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007973 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007974}
7975#endif /* HAVE_SETEUID */
7976
Larry Hastings2f936352014-08-05 14:04:04 +10007977
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007978#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10007979/*[clinic input]
7980os.setegid
7981
7982 egid: gid_t
7983 /
7984
7985Set the current process's effective group id.
7986[clinic start generated code]*/
7987
Larry Hastings2f936352014-08-05 14:04:04 +10007988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007989os_setegid_impl(PyObject *module, gid_t egid)
7990/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007991{
7992 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007994 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007995}
7996#endif /* HAVE_SETEGID */
7997
Larry Hastings2f936352014-08-05 14:04:04 +10007998
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007999#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10008000/*[clinic input]
8001os.setreuid
8002
8003 ruid: uid_t
8004 euid: uid_t
8005 /
8006
8007Set the current process's real and effective user ids.
8008[clinic start generated code]*/
8009
Larry Hastings2f936352014-08-05 14:04:04 +10008010static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008011os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
8012/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008013{
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 if (setreuid(ruid, euid) < 0) {
8015 return posix_error();
8016 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008017 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008019}
8020#endif /* HAVE_SETREUID */
8021
Larry Hastings2f936352014-08-05 14:04:04 +10008022
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008023#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10008024/*[clinic input]
8025os.setregid
8026
8027 rgid: gid_t
8028 egid: gid_t
8029 /
8030
8031Set the current process's real and effective group ids.
8032[clinic start generated code]*/
8033
Larry Hastings2f936352014-08-05 14:04:04 +10008034static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008035os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
8036/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008037{
8038 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008040 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008041}
8042#endif /* HAVE_SETREGID */
8043
Larry Hastings2f936352014-08-05 14:04:04 +10008044
Guido van Rossumb6775db1994-08-01 11:34:53 +00008045#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10008046/*[clinic input]
8047os.setgid
8048 gid: gid_t
8049 /
8050
8051Set the current process's group id.
8052[clinic start generated code]*/
8053
Larry Hastings2f936352014-08-05 14:04:04 +10008054static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008055os_setgid_impl(PyObject *module, gid_t gid)
8056/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008057{
Victor Stinner8c62be82010-05-06 00:08:46 +00008058 if (setgid(gid) < 0)
8059 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008060 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008061}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008062#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00008063
Larry Hastings2f936352014-08-05 14:04:04 +10008064
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008065#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10008066/*[clinic input]
8067os.setgroups
8068
8069 groups: object
8070 /
8071
8072Set the groups of the current process to list.
8073[clinic start generated code]*/
8074
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008075static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008076os_setgroups(PyObject *module, PyObject *groups)
8077/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008078{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008079 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00008080 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00008081
Victor Stinner8c62be82010-05-06 00:08:46 +00008082 if (!PySequence_Check(groups)) {
8083 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
8084 return NULL;
8085 }
8086 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008087 if (len < 0) {
8088 return NULL;
8089 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008090 if (len > MAX_GROUPS) {
8091 PyErr_SetString(PyExc_ValueError, "too many groups");
8092 return NULL;
8093 }
8094 for(i = 0; i < len; i++) {
8095 PyObject *elem;
8096 elem = PySequence_GetItem(groups, i);
8097 if (!elem)
8098 return NULL;
8099 if (!PyLong_Check(elem)) {
8100 PyErr_SetString(PyExc_TypeError,
8101 "groups must be integers");
8102 Py_DECREF(elem);
8103 return NULL;
8104 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008105 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008106 Py_DECREF(elem);
8107 return NULL;
8108 }
8109 }
8110 Py_DECREF(elem);
8111 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008112
Victor Stinner8c62be82010-05-06 00:08:46 +00008113 if (setgroups(len, grouplist) < 0)
8114 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02008115 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008116}
8117#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008118
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008119#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
8120static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008121wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008122{
Victor Stinner8c62be82010-05-06 00:08:46 +00008123 PyObject *result;
Eddie Elizondob3966632019-11-05 07:16:14 -08008124 PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008125
Victor Stinner8c62be82010-05-06 00:08:46 +00008126 if (pid == -1)
8127 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008128
Zackery Spytz682107c2019-09-09 09:48:32 -06008129 // If wait succeeded but no child was ready to report status, ru will not
8130 // have been populated.
8131 if (pid == 0) {
8132 memset(ru, 0, sizeof(*ru));
8133 }
8134
Eddie Elizondob3966632019-11-05 07:16:14 -08008135 PyObject *m = PyImport_ImportModuleNoBlock("resource");
8136 if (m == NULL)
8137 return NULL;
Victor Stinner1c2fa782020-05-10 11:05:29 +02008138 struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage);
Eddie Elizondob3966632019-11-05 07:16:14 -08008139 Py_DECREF(m);
8140 if (struct_rusage == NULL)
8141 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008142
Victor Stinner8c62be82010-05-06 00:08:46 +00008143 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
8144 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
Eddie Elizondoe4db1f02019-11-25 19:07:37 -08008145 Py_DECREF(struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00008146 if (!result)
8147 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008148
8149#ifndef doubletime
8150#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
8151#endif
8152
Victor Stinner8c62be82010-05-06 00:08:46 +00008153 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008154 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008156 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008157#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00008158 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
8159 SET_INT(result, 2, ru->ru_maxrss);
8160 SET_INT(result, 3, ru->ru_ixrss);
8161 SET_INT(result, 4, ru->ru_idrss);
8162 SET_INT(result, 5, ru->ru_isrss);
8163 SET_INT(result, 6, ru->ru_minflt);
8164 SET_INT(result, 7, ru->ru_majflt);
8165 SET_INT(result, 8, ru->ru_nswap);
8166 SET_INT(result, 9, ru->ru_inblock);
8167 SET_INT(result, 10, ru->ru_oublock);
8168 SET_INT(result, 11, ru->ru_msgsnd);
8169 SET_INT(result, 12, ru->ru_msgrcv);
8170 SET_INT(result, 13, ru->ru_nsignals);
8171 SET_INT(result, 14, ru->ru_nvcsw);
8172 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008173#undef SET_INT
8174
Victor Stinner8c62be82010-05-06 00:08:46 +00008175 if (PyErr_Occurred()) {
8176 Py_DECREF(result);
8177 return NULL;
8178 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008179
Victor Stinner8c62be82010-05-06 00:08:46 +00008180 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008181}
8182#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
8183
Larry Hastings2f936352014-08-05 14:04:04 +10008184
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008185#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10008186/*[clinic input]
8187os.wait3
8188
8189 options: int
8190Wait for completion of a child process.
8191
8192Returns a tuple of information about the child process:
8193 (pid, status, rusage)
8194[clinic start generated code]*/
8195
Larry Hastings2f936352014-08-05 14:04:04 +10008196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008197os_wait3_impl(PyObject *module, int options)
8198/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008199{
Victor Stinner8c62be82010-05-06 00:08:46 +00008200 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008201 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008202 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008203 WAIT_TYPE status;
8204 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008205
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008206 do {
8207 Py_BEGIN_ALLOW_THREADS
8208 pid = wait3(&status, options, &ru);
8209 Py_END_ALLOW_THREADS
8210 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8211 if (pid < 0)
8212 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008213
Victor Stinner1c2fa782020-05-10 11:05:29 +02008214 return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008215}
8216#endif /* HAVE_WAIT3 */
8217
Larry Hastings2f936352014-08-05 14:04:04 +10008218
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008219#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10008220/*[clinic input]
8221
8222os.wait4
8223
8224 pid: pid_t
8225 options: int
8226
8227Wait for completion of a specific child process.
8228
8229Returns a tuple of information about the child process:
8230 (pid, status, rusage)
8231[clinic start generated code]*/
8232
Larry Hastings2f936352014-08-05 14:04:04 +10008233static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008234os_wait4_impl(PyObject *module, pid_t pid, int options)
8235/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008236{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008237 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008238 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008239 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008240 WAIT_TYPE status;
8241 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008242
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008243 do {
8244 Py_BEGIN_ALLOW_THREADS
8245 res = wait4(pid, &status, options, &ru);
8246 Py_END_ALLOW_THREADS
8247 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8248 if (res < 0)
8249 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008250
Victor Stinner1c2fa782020-05-10 11:05:29 +02008251 return wait_helper(module, res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008252}
8253#endif /* HAVE_WAIT4 */
8254
Larry Hastings2f936352014-08-05 14:04:04 +10008255
Ross Lagerwall7807c352011-03-17 20:20:30 +02008256#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10008257/*[clinic input]
8258os.waitid
8259
8260 idtype: idtype_t
8261 Must be one of be P_PID, P_PGID or P_ALL.
8262 id: id_t
8263 The id to wait on.
8264 options: int
8265 Constructed from the ORing of one or more of WEXITED, WSTOPPED
8266 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
8267 /
8268
8269Returns the result of waiting for a process or processes.
8270
8271Returns either waitid_result or None if WNOHANG is specified and there are
8272no children in a waitable state.
8273[clinic start generated code]*/
8274
Larry Hastings2f936352014-08-05 14:04:04 +10008275static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008276os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
8277/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008278{
8279 PyObject *result;
8280 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008281 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008282 siginfo_t si;
8283 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008284
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008285 do {
8286 Py_BEGIN_ALLOW_THREADS
8287 res = waitid(idtype, id, &si, options);
8288 Py_END_ALLOW_THREADS
8289 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8290 if (res < 0)
8291 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008292
8293 if (si.si_pid == 0)
8294 Py_RETURN_NONE;
8295
Hai Shif707d942020-03-16 21:15:01 +08008296 PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008297 result = PyStructSequence_New((PyTypeObject *)WaitidResultType);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008298 if (!result)
8299 return NULL;
8300
8301 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02008302 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008303 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
8304 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
8305 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
8306 if (PyErr_Occurred()) {
8307 Py_DECREF(result);
8308 return NULL;
8309 }
8310
8311 return result;
8312}
Larry Hastings2f936352014-08-05 14:04:04 +10008313#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008314
Larry Hastings2f936352014-08-05 14:04:04 +10008315
8316#if defined(HAVE_WAITPID)
8317/*[clinic input]
8318os.waitpid
8319 pid: pid_t
8320 options: int
8321 /
8322
8323Wait for completion of a given child process.
8324
8325Returns a tuple of information regarding the child process:
8326 (pid, status)
8327
8328The options argument is ignored on Windows.
8329[clinic start generated code]*/
8330
Larry Hastings2f936352014-08-05 14:04:04 +10008331static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008332os_waitpid_impl(PyObject *module, pid_t pid, int options)
8333/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008334{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008335 pid_t res;
8336 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008337 WAIT_TYPE status;
8338 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008339
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008340 do {
8341 Py_BEGIN_ALLOW_THREADS
8342 res = waitpid(pid, &status, options);
8343 Py_END_ALLOW_THREADS
8344 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8345 if (res < 0)
8346 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008347
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008348 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00008349}
Tim Petersab034fa2002-02-01 11:27:43 +00008350#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00008351/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10008352/*[clinic input]
8353os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07008354 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10008355 options: int
8356 /
8357
8358Wait for completion of a given process.
8359
8360Returns a tuple of information regarding the process:
8361 (pid, status << 8)
8362
8363The options argument is ignored on Windows.
8364[clinic start generated code]*/
8365
Larry Hastings2f936352014-08-05 14:04:04 +10008366static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07008367os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07008368/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008369{
8370 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07008371 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008372 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008373
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008374 do {
8375 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08008376 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008377 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08008378 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008379 Py_END_ALLOW_THREADS
8380 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02008381 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008382 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008383
Victor Stinner9bee32b2020-04-22 16:30:35 +02008384 unsigned long long ustatus = (unsigned int)status;
8385
Victor Stinner8c62be82010-05-06 00:08:46 +00008386 /* shift the status left a byte so this is more like the POSIX waitpid */
Victor Stinner9bee32b2020-04-22 16:30:35 +02008387 return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00008388}
Larry Hastings2f936352014-08-05 14:04:04 +10008389#endif
8390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008391
Guido van Rossumad0ee831995-03-01 10:34:45 +00008392#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10008393/*[clinic input]
8394os.wait
8395
8396Wait for completion of a child process.
8397
8398Returns a tuple of information about the child process:
8399 (pid, status)
8400[clinic start generated code]*/
8401
Larry Hastings2f936352014-08-05 14:04:04 +10008402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008403os_wait_impl(PyObject *module)
8404/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00008405{
Victor Stinner8c62be82010-05-06 00:08:46 +00008406 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008407 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008408 WAIT_TYPE status;
8409 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00008410
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008411 do {
8412 Py_BEGIN_ALLOW_THREADS
8413 pid = wait(&status);
8414 Py_END_ALLOW_THREADS
8415 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8416 if (pid < 0)
8417 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008418
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00008420}
Larry Hastings2f936352014-08-05 14:04:04 +10008421#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00008422
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08008423#if defined(__linux__) && defined(__NR_pidfd_open)
8424/*[clinic input]
8425os.pidfd_open
8426 pid: pid_t
8427 flags: unsigned_int = 0
8428
8429Return a file descriptor referring to the process *pid*.
8430
8431The descriptor can be used to perform process management without races and
8432signals.
8433[clinic start generated code]*/
8434
8435static PyObject *
8436os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags)
8437/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/
8438{
8439 int fd = syscall(__NR_pidfd_open, pid, flags);
8440 if (fd < 0) {
8441 return posix_error();
8442 }
8443 return PyLong_FromLong(fd);
8444}
8445#endif
8446
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008447
Larry Hastings9cf065c2012-06-22 16:30:09 -07008448#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008449/*[clinic input]
8450os.readlink
8451
8452 path: path_t
8453 *
8454 dir_fd: dir_fd(requires='readlinkat') = None
8455
8456Return a string representing the path to which the symbolic link points.
8457
8458If dir_fd is not None, it should be a file descriptor open to a directory,
8459and path should be relative; path will then be relative to that directory.
8460
8461dir_fd may not be implemented on your platform. If it is unavailable,
8462using it will raise a NotImplementedError.
8463[clinic start generated code]*/
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008464
Barry Warsaw53699e91996-12-10 23:23:01 +00008465static PyObject *
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008466os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
8467/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008468{
Berker Peksage0b5b202018-08-15 13:03:41 +03008469#if defined(HAVE_READLINK)
Christian Heimes3cb091e2016-09-23 20:24:28 +02008470 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07008471 ssize_t length;
Ronald Oussoren41761932020-11-08 10:05:27 +01008472#ifdef HAVE_READLINKAT
8473 int readlinkat_unavailable = 0;
8474#endif
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008475
8476 Py_BEGIN_ALLOW_THREADS
8477#ifdef HAVE_READLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +01008478 if (dir_fd != DEFAULT_DIR_FD) {
8479 if (HAVE_READLINKAT_RUNTIME) {
8480 length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN);
8481 } else {
8482 readlinkat_unavailable = 1;
8483 }
8484 } else
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008485#endif
8486 length = readlink(path->narrow, buffer, MAXPATHLEN);
8487 Py_END_ALLOW_THREADS
8488
Ronald Oussoren41761932020-11-08 10:05:27 +01008489#ifdef HAVE_READLINKAT
8490 if (readlinkat_unavailable) {
8491 argument_unavailable_error(NULL, "dir_fd");
8492 return NULL;
8493 }
8494#endif
8495
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008496 if (length < 0) {
8497 return path_error(path);
8498 }
8499 buffer[length] = '\0';
8500
8501 if (PyUnicode_Check(path->object))
8502 return PyUnicode_DecodeFSDefaultAndSize(buffer, length);
8503 else
8504 return PyBytes_FromStringAndSize(buffer, length);
Berker Peksage0b5b202018-08-15 13:03:41 +03008505#elif defined(MS_WINDOWS)
8506 DWORD n_bytes_returned;
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008507 DWORD io_result = 0;
Berker Peksage0b5b202018-08-15 13:03:41 +03008508 HANDLE reparse_point_handle;
Berker Peksage0b5b202018-08-15 13:03:41 +03008509 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
8510 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Steve Dower993ac922019-09-03 12:50:51 -07008511 PyObject *result = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00008512
Larry Hastings2f936352014-08-05 14:04:04 +10008513 /* First get a handle to the reparse point */
8514 Py_BEGIN_ALLOW_THREADS
8515 reparse_point_handle = CreateFileW(
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008516 path->wide,
Larry Hastings2f936352014-08-05 14:04:04 +10008517 0,
8518 0,
8519 0,
8520 OPEN_EXISTING,
8521 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
8522 0);
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008523 if (reparse_point_handle != INVALID_HANDLE_VALUE) {
8524 /* New call DeviceIoControl to read the reparse point */
8525 io_result = DeviceIoControl(
8526 reparse_point_handle,
8527 FSCTL_GET_REPARSE_POINT,
8528 0, 0, /* in buffer */
8529 target_buffer, sizeof(target_buffer),
8530 &n_bytes_returned,
8531 0 /* we're not using OVERLAPPED_IO */
8532 );
8533 CloseHandle(reparse_point_handle);
Berker Peksage0b5b202018-08-15 13:03:41 +03008534 }
Larry Hastings2f936352014-08-05 14:04:04 +10008535 Py_END_ALLOW_THREADS
8536
Berker Peksage0b5b202018-08-15 13:03:41 +03008537 if (io_result == 0) {
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008538 return path_error(path);
Berker Peksage0b5b202018-08-15 13:03:41 +03008539 }
Larry Hastings2f936352014-08-05 14:04:04 +10008540
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008541 wchar_t *name = NULL;
8542 Py_ssize_t nameLen = 0;
8543 if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK)
Larry Hastings2f936352014-08-05 14:04:04 +10008544 {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008545 name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
8546 rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset);
8547 nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
Larry Hastings2f936352014-08-05 14:04:04 +10008548 }
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008549 else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
8550 {
8551 name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer +
8552 rdb->MountPointReparseBuffer.SubstituteNameOffset);
8553 nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
8554 }
8555 else
8556 {
8557 PyErr_SetString(PyExc_ValueError, "not a symbolic link");
8558 }
8559 if (name) {
8560 if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) {
8561 /* Our buffer is mutable, so this is okay */
8562 name[1] = L'\\';
8563 }
8564 result = PyUnicode_FromWideChar(name, nameLen);
Steve Dower993ac922019-09-03 12:50:51 -07008565 if (result && path->narrow) {
Steve Dowerdf2d4a62019-08-21 15:27:33 -07008566 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
8567 }
Berker Peksage0b5b202018-08-15 13:03:41 +03008568 }
Serhiy Storchaka12a69db2018-09-17 15:38:27 +03008569 return result;
Berker Peksage0b5b202018-08-15 13:03:41 +03008570#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008571}
Berker Peksage0b5b202018-08-15 13:03:41 +03008572#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008573
Larry Hastings9cf065c2012-06-22 16:30:09 -07008574#if defined(MS_WINDOWS)
8575
Steve Dower6921e732018-03-05 14:26:08 -08008576/* Remove the last portion of the path - return 0 on success */
8577static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008578_dirnameW(WCHAR *path)
8579{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008580 WCHAR *ptr;
Steve Dower6921e732018-03-05 14:26:08 -08008581 size_t length = wcsnlen_s(path, MAX_PATH);
8582 if (length == MAX_PATH) {
8583 return -1;
8584 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008585
8586 /* walk the path from the end until a backslash is encountered */
Steve Dower6921e732018-03-05 14:26:08 -08008587 for(ptr = path + length; ptr != path; ptr--) {
8588 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04008589 break;
Steve Dower6921e732018-03-05 14:26:08 -08008590 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008591 }
8592 *ptr = 0;
Steve Dower6921e732018-03-05 14:26:08 -08008593 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008594}
8595
Minmin Gong7f21c9a2020-05-18 09:17:19 -07008596#endif
8597
8598#ifdef HAVE_SYMLINK
8599
8600#if defined(MS_WINDOWS)
8601
Victor Stinner31b3b922013-06-05 01:49:17 +02008602/* Is this path absolute? */
8603static int
8604_is_absW(const WCHAR *path)
8605{
Steve Dower6921e732018-03-05 14:26:08 -08008606 return path[0] == L'\\' || path[0] == L'/' ||
8607 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04008608}
8609
Steve Dower6921e732018-03-05 14:26:08 -08008610/* join root and rest with a backslash - return 0 on success */
8611static int
Victor Stinner31b3b922013-06-05 01:49:17 +02008612_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
8613{
Victor Stinner31b3b922013-06-05 01:49:17 +02008614 if (_is_absW(rest)) {
Steve Dower6921e732018-03-05 14:26:08 -08008615 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008616 }
8617
Steve Dower6921e732018-03-05 14:26:08 -08008618 if (wcscpy_s(dest_path, MAX_PATH, root)) {
8619 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04008620 }
Steve Dower6921e732018-03-05 14:26:08 -08008621
8622 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
8623 return -1;
8624 }
8625
8626 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04008627}
8628
Victor Stinner31b3b922013-06-05 01:49:17 +02008629/* Return True if the path at src relative to dest is a directory */
8630static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008631_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04008632{
Jason R. Coombs3a092862013-05-27 23:21:28 -04008633 WIN32_FILE_ATTRIBUTE_DATA src_info;
8634 WCHAR dest_parent[MAX_PATH];
8635 WCHAR src_resolved[MAX_PATH] = L"";
8636
8637 /* dest_parent = os.path.dirname(dest) */
Steve Dower6921e732018-03-05 14:26:08 -08008638 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
8639 _dirnameW(dest_parent)) {
8640 return 0;
8641 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008642 /* src_resolved = os.path.join(dest_parent, src) */
Steve Dower6921e732018-03-05 14:26:08 -08008643 if (_joinW(src_resolved, dest_parent, src)) {
8644 return 0;
8645 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008646 return (
8647 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
8648 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
8649 );
8650}
Larry Hastings9cf065c2012-06-22 16:30:09 -07008651#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008652
Larry Hastings2f936352014-08-05 14:04:04 +10008653
8654/*[clinic input]
8655os.symlink
8656 src: path_t
8657 dst: path_t
8658 target_is_directory: bool = False
8659 *
8660 dir_fd: dir_fd(requires='symlinkat')=None
8661
8662# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
8663
8664Create a symbolic link pointing to src named dst.
8665
8666target_is_directory is required on Windows if the target is to be
8667 interpreted as a directory. (On Windows, symlink requires
8668 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
8669 target_is_directory is ignored on non-Windows platforms.
8670
8671If dir_fd is not None, it should be a file descriptor open to a directory,
8672 and path should be relative; path will then be relative to that directory.
8673dir_fd may not be implemented on your platform.
8674 If it is unavailable, using it will raise a NotImplementedError.
8675
8676[clinic start generated code]*/
8677
Larry Hastings2f936352014-08-05 14:04:04 +10008678static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008679os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04008680 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008681/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008682{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008683#ifdef MS_WINDOWS
8684 DWORD result;
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008685 DWORD flags = 0;
8686
8687 /* Assumed true, set to false if detected to not be available. */
8688 static int windows_has_symlink_unprivileged_flag = TRUE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008689#else
8690 int result;
Ronald Oussoren41761932020-11-08 10:05:27 +01008691#ifdef HAVE_SYMLINKAT
8692 int symlinkat_unavailable = 0;
8693#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07008694#endif
8695
Saiyang Gou7514f4f2020-02-12 23:47:42 -08008696 if (PySys_Audit("os.symlink", "OOi", src->object, dst->object,
8697 dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) {
8698 return NULL;
8699 }
8700
Larry Hastings9cf065c2012-06-22 16:30:09 -07008701#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008702
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008703 if (windows_has_symlink_unprivileged_flag) {
8704 /* Allow non-admin symlinks if system allows it. */
8705 flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
8706 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04008707
Larry Hastings9cf065c2012-06-22 16:30:09 -07008708 Py_BEGIN_ALLOW_THREADS
Steve Dower6921e732018-03-05 14:26:08 -08008709 _Py_BEGIN_SUPPRESS_IPH
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008710 /* if src is a directory, ensure flags==1 (target_is_directory bit) */
8711 if (target_is_directory || _check_dirW(src->wide, dst->wide)) {
8712 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
8713 }
8714
8715 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
Steve Dower6921e732018-03-05 14:26:08 -08008716 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07008717 Py_END_ALLOW_THREADS
8718
Vidar Tonaas Fauske0e107662019-04-09 20:19:46 +02008719 if (windows_has_symlink_unprivileged_flag && !result &&
8720 ERROR_INVALID_PARAMETER == GetLastError()) {
8721
8722 Py_BEGIN_ALLOW_THREADS
8723 _Py_BEGIN_SUPPRESS_IPH
8724 /* This error might be caused by
8725 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported.
8726 Try again, and update windows_has_symlink_unprivileged_flag if we
8727 are successful this time.
8728
8729 NOTE: There is a risk of a race condition here if there are other
8730 conditions than the flag causing ERROR_INVALID_PARAMETER, and
8731 another process (or thread) changes that condition in between our
8732 calls to CreateSymbolicLink.
8733 */
8734 flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
8735 result = CreateSymbolicLinkW(dst->wide, src->wide, flags);
8736 _Py_END_SUPPRESS_IPH
8737 Py_END_ALLOW_THREADS
8738
8739 if (result || ERROR_INVALID_PARAMETER != GetLastError()) {
8740 windows_has_symlink_unprivileged_flag = FALSE;
8741 }
8742 }
8743
Larry Hastings2f936352014-08-05 14:04:04 +10008744 if (!result)
8745 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008746
8747#else
8748
Steve Dower6921e732018-03-05 14:26:08 -08008749 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
8750 PyErr_SetString(PyExc_ValueError,
8751 "symlink: src and dst must be the same type");
8752 return NULL;
8753 }
8754
Larry Hastings9cf065c2012-06-22 16:30:09 -07008755 Py_BEGIN_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +01008756#ifdef HAVE_SYMLINKAT
8757 if (dir_fd != DEFAULT_DIR_FD) {
8758 if (HAVE_SYMLINKAT_RUNTIME) {
8759 result = symlinkat(src->narrow, dir_fd, dst->narrow);
8760 } else {
8761 symlinkat_unavailable = 1;
8762 }
8763 } else
Larry Hastings9cf065c2012-06-22 16:30:09 -07008764#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008765 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008766 Py_END_ALLOW_THREADS
8767
Ronald Oussoren41761932020-11-08 10:05:27 +01008768#ifdef HAVE_SYMLINKAT
8769 if (symlinkat_unavailable) {
8770 argument_unavailable_error(NULL, "dir_fd");
8771 return NULL;
8772 }
8773#endif
8774
Larry Hastings2f936352014-08-05 14:04:04 +10008775 if (result)
8776 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008777#endif
8778
Larry Hastings2f936352014-08-05 14:04:04 +10008779 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008780}
8781#endif /* HAVE_SYMLINK */
8782
Larry Hastings9cf065c2012-06-22 16:30:09 -07008783
Brian Curtind40e6f72010-07-08 21:39:08 +00008784
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00008785
Larry Hastings605a62d2012-06-24 04:33:36 -07008786static PyStructSequence_Field times_result_fields[] = {
8787 {"user", "user time"},
8788 {"system", "system time"},
8789 {"children_user", "user time of children"},
8790 {"children_system", "system time of children"},
8791 {"elapsed", "elapsed time since an arbitrary point in the past"},
8792 {NULL}
8793};
8794
8795PyDoc_STRVAR(times_result__doc__,
8796"times_result: Result from os.times().\n\n\
8797This object may be accessed either as a tuple of\n\
8798 (user, system, children_user, children_system, elapsed),\n\
8799or via the attributes user, system, children_user, children_system,\n\
8800and elapsed.\n\
8801\n\
8802See os.times for more information.");
8803
8804static PyStructSequence_Desc times_result_desc = {
8805 "times_result", /* name */
8806 times_result__doc__, /* doc */
8807 times_result_fields,
8808 5
8809};
8810
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008811#ifdef MS_WINDOWS
8812#define HAVE_TIMES /* mandatory, for the method table */
8813#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07008814
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008815#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07008816
8817static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +02008818build_times_result(PyObject *module, double user, double system,
Larry Hastings605a62d2012-06-24 04:33:36 -07008819 double children_user, double children_system,
8820 double elapsed)
8821{
Victor Stinner1c2fa782020-05-10 11:05:29 +02008822 PyObject *TimesResultType = get_posix_state(module)->TimesResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -08008823 PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType);
Larry Hastings605a62d2012-06-24 04:33:36 -07008824 if (value == NULL)
8825 return NULL;
8826
8827#define SET(i, field) \
8828 { \
8829 PyObject *o = PyFloat_FromDouble(field); \
8830 if (!o) { \
8831 Py_DECREF(value); \
8832 return NULL; \
8833 } \
8834 PyStructSequence_SET_ITEM(value, i, o); \
8835 } \
8836
8837 SET(0, user);
8838 SET(1, system);
8839 SET(2, children_user);
8840 SET(3, children_system);
8841 SET(4, elapsed);
8842
8843#undef SET
8844
8845 return value;
8846}
8847
Larry Hastings605a62d2012-06-24 04:33:36 -07008848
Larry Hastings2f936352014-08-05 14:04:04 +10008849#ifndef MS_WINDOWS
8850#define NEED_TICKS_PER_SECOND
8851static long ticks_per_second = -1;
8852#endif /* MS_WINDOWS */
8853
8854/*[clinic input]
8855os.times
8856
8857Return a collection containing process timing information.
8858
8859The object returned behaves like a named tuple with these fields:
8860 (utime, stime, cutime, cstime, elapsed_time)
8861All fields are floating point numbers.
8862[clinic start generated code]*/
8863
Larry Hastings2f936352014-08-05 14:04:04 +10008864static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008865os_times_impl(PyObject *module)
8866/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008867#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008868{
Victor Stinner8c62be82010-05-06 00:08:46 +00008869 FILETIME create, exit, kernel, user;
8870 HANDLE hProc;
8871 hProc = GetCurrentProcess();
8872 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
8873 /* The fields of a FILETIME structure are the hi and lo part
8874 of a 64-bit value expressed in 100 nanosecond units.
8875 1e7 is one second in such units; 1e-7 the inverse.
8876 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
8877 */
Victor Stinner1c2fa782020-05-10 11:05:29 +02008878 return build_times_result(module,
Victor Stinner8c62be82010-05-06 00:08:46 +00008879 (double)(user.dwHighDateTime*429.4967296 +
8880 user.dwLowDateTime*1e-7),
8881 (double)(kernel.dwHighDateTime*429.4967296 +
8882 kernel.dwLowDateTime*1e-7),
8883 (double)0,
8884 (double)0,
8885 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00008886}
Larry Hastings2f936352014-08-05 14:04:04 +10008887#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008888{
Larry Hastings2f936352014-08-05 14:04:04 +10008889
8890
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008891 struct tms t;
8892 clock_t c;
8893 errno = 0;
8894 c = times(&t);
8895 if (c == (clock_t) -1)
8896 return posix_error();
Victor Stinner1c2fa782020-05-10 11:05:29 +02008897 return build_times_result(module,
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008898 (double)t.tms_utime / ticks_per_second,
8899 (double)t.tms_stime / ticks_per_second,
8900 (double)t.tms_cutime / ticks_per_second,
8901 (double)t.tms_cstime / ticks_per_second,
8902 (double)c / ticks_per_second);
8903}
Larry Hastings2f936352014-08-05 14:04:04 +10008904#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02008905#endif /* HAVE_TIMES */
8906
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008907
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008908#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008909/*[clinic input]
8910os.getsid
8911
8912 pid: pid_t
8913 /
8914
8915Call the system call getsid(pid) and return the result.
8916[clinic start generated code]*/
8917
Larry Hastings2f936352014-08-05 14:04:04 +10008918static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008919os_getsid_impl(PyObject *module, pid_t pid)
8920/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008921{
Victor Stinner8c62be82010-05-06 00:08:46 +00008922 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00008923 sid = getsid(pid);
8924 if (sid < 0)
8925 return posix_error();
8926 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008927}
8928#endif /* HAVE_GETSID */
8929
8930
Guido van Rossumb6775db1994-08-01 11:34:53 +00008931#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10008932/*[clinic input]
8933os.setsid
8934
8935Call the system call setsid().
8936[clinic start generated code]*/
8937
Larry Hastings2f936352014-08-05 14:04:04 +10008938static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008939os_setsid_impl(PyObject *module)
8940/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00008941{
Victor Stinner8c62be82010-05-06 00:08:46 +00008942 if (setsid() < 0)
8943 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008944 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008945}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008946#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008947
Larry Hastings2f936352014-08-05 14:04:04 +10008948
Guido van Rossumb6775db1994-08-01 11:34:53 +00008949#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10008950/*[clinic input]
8951os.setpgid
8952
8953 pid: pid_t
8954 pgrp: pid_t
8955 /
8956
8957Call the system call setpgid(pid, pgrp).
8958[clinic start generated code]*/
8959
Larry Hastings2f936352014-08-05 14:04:04 +10008960static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008961os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
8962/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008963{
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 if (setpgid(pid, pgrp) < 0)
8965 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008966 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00008967}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008968#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00008969
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008970
Guido van Rossumb6775db1994-08-01 11:34:53 +00008971#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008972/*[clinic input]
8973os.tcgetpgrp
8974
8975 fd: int
8976 /
8977
8978Return the process group associated with the terminal specified by fd.
8979[clinic start generated code]*/
8980
Larry Hastings2f936352014-08-05 14:04:04 +10008981static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008982os_tcgetpgrp_impl(PyObject *module, int fd)
8983/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008984{
8985 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00008986 if (pgid < 0)
8987 return posix_error();
8988 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00008989}
Guido van Rossumb6775db1994-08-01 11:34:53 +00008990#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00008991
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008992
Guido van Rossumb6775db1994-08-01 11:34:53 +00008993#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10008994/*[clinic input]
8995os.tcsetpgrp
8996
8997 fd: int
8998 pgid: pid_t
8999 /
9000
9001Set the process group associated with the terminal specified by fd.
9002[clinic start generated code]*/
9003
Larry Hastings2f936352014-08-05 14:04:04 +10009004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009005os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
9006/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009007{
Victor Stinner8c62be82010-05-06 00:08:46 +00009008 if (tcsetpgrp(fd, pgid) < 0)
9009 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009010 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00009011}
Guido van Rossumb6775db1994-08-01 11:34:53 +00009012#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00009013
Guido van Rossum687dd131993-05-17 08:34:16 +00009014/* Functions acting on file descriptors */
9015
Victor Stinnerdaf45552013-08-28 00:53:59 +02009016#ifdef O_CLOEXEC
9017extern int _Py_open_cloexec_works;
9018#endif
9019
Larry Hastings2f936352014-08-05 14:04:04 +10009020
9021/*[clinic input]
9022os.open -> int
9023 path: path_t
9024 flags: int
9025 mode: int = 0o777
9026 *
9027 dir_fd: dir_fd(requires='openat') = None
9028
9029# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
9030
9031Open a file for low level IO. Returns a file descriptor (integer).
9032
9033If dir_fd is not None, it should be a file descriptor open to a directory,
9034 and path should be relative; path will then be relative to that directory.
9035dir_fd may not be implemented on your platform.
9036 If it is unavailable, using it will raise a NotImplementedError.
9037[clinic start generated code]*/
9038
Larry Hastings2f936352014-08-05 14:04:04 +10009039static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009040os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
9041/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009042{
9043 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009044 int async_err = 0;
Ronald Oussoren41761932020-11-08 10:05:27 +01009045#ifdef HAVE_OPENAT
9046 int openat_unavailable = 0;
9047#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009048
Victor Stinnerdaf45552013-08-28 00:53:59 +02009049#ifdef O_CLOEXEC
9050 int *atomic_flag_works = &_Py_open_cloexec_works;
9051#elif !defined(MS_WINDOWS)
9052 int *atomic_flag_works = NULL;
9053#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00009054
Victor Stinnerdaf45552013-08-28 00:53:59 +02009055#ifdef MS_WINDOWS
9056 flags |= O_NOINHERIT;
9057#elif defined(O_CLOEXEC)
9058 flags |= O_CLOEXEC;
9059#endif
9060
Steve Dowerb82e17e2019-05-23 08:45:22 -07009061 if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) {
9062 return -1;
9063 }
9064
Steve Dower8fc89802015-04-12 00:26:27 -04009065 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009066 do {
9067 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07009068#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009069 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009070#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07009071#ifdef HAVE_OPENAT
Ronald Oussoren41761932020-11-08 10:05:27 +01009072 if (dir_fd != DEFAULT_DIR_FD) {
9073 if (HAVE_OPENAT_RUNTIME) {
9074 fd = openat(dir_fd, path->narrow, flags, mode);
9075
9076 } else {
9077 openat_unavailable = 1;
9078 fd = -1;
9079 }
9080 } else
Steve Dower6230aaf2016-09-09 09:03:15 -07009081#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009082 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07009083#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009084 Py_END_ALLOW_THREADS
9085 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009086 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00009087
Ronald Oussoren41761932020-11-08 10:05:27 +01009088#ifdef HAVE_OPENAT
9089 if (openat_unavailable) {
9090 argument_unavailable_error(NULL, "dir_fd");
9091 return -1;
9092 }
9093#endif
9094
Victor Stinnerd3ffd322015-09-15 10:11:03 +02009095 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009096 if (!async_err)
9097 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10009098 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009099 }
9100
Victor Stinnerdaf45552013-08-28 00:53:59 +02009101#ifndef MS_WINDOWS
9102 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
9103 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10009104 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009105 }
9106#endif
9107
Larry Hastings2f936352014-08-05 14:04:04 +10009108 return fd;
9109}
9110
9111
9112/*[clinic input]
9113os.close
9114
9115 fd: int
9116
9117Close a file descriptor.
9118[clinic start generated code]*/
9119
Barry Warsaw53699e91996-12-10 23:23:01 +00009120static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009121os_close_impl(PyObject *module, int fd)
9122/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00009123{
Larry Hastings2f936352014-08-05 14:04:04 +10009124 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009125 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
9126 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
9127 * for more details.
9128 */
Victor Stinner8c62be82010-05-06 00:08:46 +00009129 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009130 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009131 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04009132 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009133 Py_END_ALLOW_THREADS
9134 if (res < 0)
9135 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009136 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00009137}
9138
Larry Hastings2f936352014-08-05 14:04:04 +10009139/*[clinic input]
9140os.closerange
9141
9142 fd_low: int
9143 fd_high: int
9144 /
9145
9146Closes all file descriptors in [fd_low, fd_high), ignoring errors.
9147[clinic start generated code]*/
9148
Larry Hastings2f936352014-08-05 14:04:04 +10009149static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009150os_closerange_impl(PyObject *module, int fd_low, int fd_high)
9151/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009152{
Victor Stinner8c62be82010-05-06 00:08:46 +00009153 Py_BEGIN_ALLOW_THREADS
Kyle Evansc230fde2020-10-11 13:54:11 -05009154 _Py_closerange(fd_low, fd_high - 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00009155 Py_END_ALLOW_THREADS
9156 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00009157}
9158
9159
Larry Hastings2f936352014-08-05 14:04:04 +10009160/*[clinic input]
9161os.dup -> int
9162
9163 fd: int
9164 /
9165
9166Return a duplicate of a file descriptor.
9167[clinic start generated code]*/
9168
Larry Hastings2f936352014-08-05 14:04:04 +10009169static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009170os_dup_impl(PyObject *module, int fd)
9171/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009172{
9173 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00009174}
9175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009176
Larry Hastings2f936352014-08-05 14:04:04 +10009177/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009178os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10009179 fd: int
9180 fd2: int
9181 inheritable: bool=True
9182
9183Duplicate file descriptor.
9184[clinic start generated code]*/
9185
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009186static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009187os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009188/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009189{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01009190 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009191#if defined(HAVE_DUP3) && \
9192 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
9193 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Alexey Izbyshevb3caf382018-02-20 10:25:46 +03009194 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009195#endif
9196
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009197 if (fd < 0 || fd2 < 0) {
9198 posix_error();
9199 return -1;
9200 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009201
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009202 /* dup2() can fail with EINTR if the target FD is already open, because it
9203 * then has to be closed. See os_close_impl() for why we don't handle EINTR
9204 * upon close(), and therefore below.
9205 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02009206#ifdef MS_WINDOWS
9207 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009208 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009209 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04009210 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02009211 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009212 if (res < 0) {
9213 posix_error();
9214 return -1;
9215 }
9216 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02009217
9218 /* Character files like console cannot be make non-inheritable */
9219 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9220 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009221 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009222 }
9223
9224#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
9225 Py_BEGIN_ALLOW_THREADS
9226 if (!inheritable)
9227 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
9228 else
9229 res = dup2(fd, fd2);
9230 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009231 if (res < 0) {
9232 posix_error();
9233 return -1;
9234 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009235
9236#else
9237
9238#ifdef HAVE_DUP3
9239 if (!inheritable && dup3_works != 0) {
9240 Py_BEGIN_ALLOW_THREADS
9241 res = dup3(fd, fd2, O_CLOEXEC);
9242 Py_END_ALLOW_THREADS
9243 if (res < 0) {
9244 if (dup3_works == -1)
9245 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009246 if (dup3_works) {
9247 posix_error();
9248 return -1;
9249 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009250 }
9251 }
9252
9253 if (inheritable || dup3_works == 0)
9254 {
9255#endif
9256 Py_BEGIN_ALLOW_THREADS
9257 res = dup2(fd, fd2);
9258 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009259 if (res < 0) {
9260 posix_error();
9261 return -1;
9262 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02009263
9264 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
9265 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009266 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02009267 }
9268#ifdef HAVE_DUP3
9269 }
9270#endif
9271
9272#endif
9273
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08009274 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00009275}
9276
Larry Hastings2f936352014-08-05 14:04:04 +10009277
Ross Lagerwall7807c352011-03-17 20:20:30 +02009278#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10009279/*[clinic input]
9280os.lockf
9281
9282 fd: int
9283 An open file descriptor.
9284 command: int
9285 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
9286 length: Py_off_t
9287 The number of bytes to lock, starting at the current position.
9288 /
9289
9290Apply, test or remove a POSIX lock on an open file descriptor.
9291
9292[clinic start generated code]*/
9293
Larry Hastings2f936352014-08-05 14:04:04 +10009294static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009295os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
9296/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009297{
9298 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009299
Saiyang Gou7514f4f2020-02-12 23:47:42 -08009300 if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) {
9301 return NULL;
9302 }
9303
Ross Lagerwall7807c352011-03-17 20:20:30 +02009304 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009305 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009306 Py_END_ALLOW_THREADS
9307
9308 if (res < 0)
9309 return posix_error();
9310
9311 Py_RETURN_NONE;
9312}
Larry Hastings2f936352014-08-05 14:04:04 +10009313#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009314
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009315
Larry Hastings2f936352014-08-05 14:04:04 +10009316/*[clinic input]
9317os.lseek -> Py_off_t
9318
9319 fd: int
9320 position: Py_off_t
9321 how: int
9322 /
9323
9324Set the position of a file descriptor. Return the new position.
9325
9326Return the new cursor position in number of bytes
9327relative to the beginning of the file.
9328[clinic start generated code]*/
9329
Larry Hastings2f936352014-08-05 14:04:04 +10009330static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009331os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
9332/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009333{
9334 Py_off_t result;
9335
Guido van Rossum687dd131993-05-17 08:34:16 +00009336#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00009337 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
9338 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10009339 case 0: how = SEEK_SET; break;
9340 case 1: how = SEEK_CUR; break;
9341 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00009342 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009343#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009344
Victor Stinner8c62be82010-05-06 00:08:46 +00009345 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009346 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02009347#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009348 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009349#else
Larry Hastings2f936352014-08-05 14:04:04 +10009350 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00009351#endif
Steve Dower8fc89802015-04-12 00:26:27 -04009352 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10009354 if (result < 0)
9355 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00009356
Larry Hastings2f936352014-08-05 14:04:04 +10009357 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00009358}
9359
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009360
Larry Hastings2f936352014-08-05 14:04:04 +10009361/*[clinic input]
9362os.read
9363 fd: int
9364 length: Py_ssize_t
9365 /
9366
9367Read from a file descriptor. Returns a bytes object.
9368[clinic start generated code]*/
9369
Larry Hastings2f936352014-08-05 14:04:04 +10009370static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009371os_read_impl(PyObject *module, int fd, Py_ssize_t length)
9372/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009373{
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 Py_ssize_t n;
9375 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10009376
9377 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 errno = EINVAL;
9379 return posix_error();
9380 }
Larry Hastings2f936352014-08-05 14:04:04 +10009381
Victor Stinner9a0d7a72018-11-22 15:03:40 +01009382 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10009383
9384 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 if (buffer == NULL)
9386 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009387
Victor Stinner66aab0c2015-03-19 22:53:20 +01009388 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
9389 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01009391 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 }
Larry Hastings2f936352014-08-05 14:04:04 +10009393
9394 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10009396
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00009398}
9399
Ross Lagerwall7807c352011-03-17 20:20:30 +02009400#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009401 || defined(__APPLE__))) \
9402 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
9403 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
9404static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009405iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009406{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009407 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009408
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009409 *iov = PyMem_New(struct iovec, cnt);
9410 if (*iov == NULL) {
9411 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009412 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009413 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009414
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009415 *buf = PyMem_New(Py_buffer, cnt);
9416 if (*buf == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01009417 PyMem_Free(*iov);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009418 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01009419 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009420 }
9421
9422 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009423 PyObject *item = PySequence_GetItem(seq, i);
9424 if (item == NULL)
9425 goto fail;
9426 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
9427 Py_DECREF(item);
9428 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009429 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009430 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009431 (*iov)[i].iov_base = (*buf)[i].buf;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009432 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009433 }
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009434 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009435
9436fail:
Victor Stinner00d7abd2020-12-01 09:56:42 +01009437 PyMem_Free(*iov);
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02009438 for (j = 0; j < i; j++) {
9439 PyBuffer_Release(&(*buf)[j]);
9440 }
Victor Stinner00d7abd2020-12-01 09:56:42 +01009441 PyMem_Free(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01009442 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009443}
9444
9445static void
9446iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
9447{
9448 int i;
Victor Stinner00d7abd2020-12-01 09:56:42 +01009449 PyMem_Free(iov);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009450 for (i = 0; i < cnt; i++) {
9451 PyBuffer_Release(&buf[i]);
9452 }
Victor Stinner00d7abd2020-12-01 09:56:42 +01009453 PyMem_Free(buf);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009454}
9455#endif
9456
Larry Hastings2f936352014-08-05 14:04:04 +10009457
Ross Lagerwall7807c352011-03-17 20:20:30 +02009458#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10009459/*[clinic input]
9460os.readv -> Py_ssize_t
9461
9462 fd: int
9463 buffers: object
9464 /
9465
9466Read from a file descriptor fd into an iterable of buffers.
9467
9468The buffers should be mutable buffers accepting bytes.
9469readv will transfer data into each buffer until it is full
9470and then move on to the next buffer in the sequence to hold
9471the rest of the data.
9472
9473readv returns the total number of bytes read,
9474which may be less than the total capacity of all the buffers.
9475[clinic start generated code]*/
9476
Larry Hastings2f936352014-08-05 14:04:04 +10009477static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009478os_readv_impl(PyObject *module, int fd, PyObject *buffers)
9479/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009480{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009481 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009482 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009483 struct iovec *iov;
9484 Py_buffer *buf;
9485
Larry Hastings2f936352014-08-05 14:04:04 +10009486 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009487 PyErr_SetString(PyExc_TypeError,
9488 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10009489 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009490 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02009491
Larry Hastings2f936352014-08-05 14:04:04 +10009492 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009493 if (cnt < 0)
9494 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10009495
9496 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
9497 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009498
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009499 do {
9500 Py_BEGIN_ALLOW_THREADS
9501 n = readv(fd, iov, cnt);
9502 Py_END_ALLOW_THREADS
9503 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02009504
9505 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10009506 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009507 if (!async_err)
9508 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10009509 return -1;
9510 }
Victor Stinner57ddf782014-01-08 15:21:28 +01009511
Larry Hastings2f936352014-08-05 14:04:04 +10009512 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009513}
Larry Hastings2f936352014-08-05 14:04:04 +10009514#endif /* HAVE_READV */
9515
Ross Lagerwall7807c352011-03-17 20:20:30 +02009516
9517#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10009518/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10009519os.pread
9520
9521 fd: int
Dong-hee Naad7736f2019-09-25 14:47:04 +09009522 length: Py_ssize_t
Larry Hastings2f936352014-08-05 14:04:04 +10009523 offset: Py_off_t
9524 /
9525
9526Read a number of bytes from a file descriptor starting at a particular offset.
9527
9528Read length bytes from file descriptor fd, starting at offset bytes from
9529the beginning of the file. The file offset remains unchanged.
9530[clinic start generated code]*/
9531
Larry Hastings2f936352014-08-05 14:04:04 +10009532static PyObject *
Dong-hee Naad7736f2019-09-25 14:47:04 +09009533os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
9534/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009535{
Ross Lagerwall7807c352011-03-17 20:20:30 +02009536 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009537 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009538 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009539
Larry Hastings2f936352014-08-05 14:04:04 +10009540 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02009541 errno = EINVAL;
9542 return posix_error();
9543 }
Larry Hastings2f936352014-08-05 14:04:04 +10009544 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009545 if (buffer == NULL)
9546 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009547
9548 do {
9549 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04009550 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009551 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04009552 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009553 Py_END_ALLOW_THREADS
9554 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9555
Ross Lagerwall7807c352011-03-17 20:20:30 +02009556 if (n < 0) {
9557 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009558 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009559 }
Larry Hastings2f936352014-08-05 14:04:04 +10009560 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02009561 _PyBytes_Resize(&buffer, n);
9562 return buffer;
9563}
Larry Hastings2f936352014-08-05 14:04:04 +10009564#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009565
Pablo Galindo4defba32018-01-27 16:16:37 +00009566#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
9567/*[clinic input]
9568os.preadv -> Py_ssize_t
9569
9570 fd: int
9571 buffers: object
9572 offset: Py_off_t
9573 flags: int = 0
9574 /
9575
9576Reads from a file descriptor into a number of mutable bytes-like objects.
9577
9578Combines the functionality of readv() and pread(). As readv(), it will
9579transfer data into each buffer until it is full and then move on to the next
9580buffer in the sequence to hold the rest of the data. Its fourth argument,
9581specifies the file offset at which the input operation is to be performed. It
9582will return the total number of bytes read (which can be less than the total
9583capacity of all the objects).
9584
9585The flags argument contains a bitwise OR of zero or more of the following flags:
9586
9587- RWF_HIPRI
9588- RWF_NOWAIT
9589
9590Using non-zero flags requires Linux 4.6 or newer.
9591[clinic start generated code]*/
9592
9593static Py_ssize_t
9594os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
9595 int flags)
9596/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
9597{
9598 Py_ssize_t cnt, n;
9599 int async_err = 0;
9600 struct iovec *iov;
9601 Py_buffer *buf;
9602
9603 if (!PySequence_Check(buffers)) {
9604 PyErr_SetString(PyExc_TypeError,
9605 "preadv2() arg 2 must be a sequence");
9606 return -1;
9607 }
9608
9609 cnt = PySequence_Size(buffers);
9610 if (cnt < 0) {
9611 return -1;
9612 }
9613
9614#ifndef HAVE_PREADV2
9615 if(flags != 0) {
9616 argument_unavailable_error("preadv2", "flags");
9617 return -1;
9618 }
9619#endif
9620
9621 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
9622 return -1;
9623 }
9624#ifdef HAVE_PREADV2
9625 do {
9626 Py_BEGIN_ALLOW_THREADS
9627 _Py_BEGIN_SUPPRESS_IPH
9628 n = preadv2(fd, iov, cnt, offset, flags);
9629 _Py_END_SUPPRESS_IPH
9630 Py_END_ALLOW_THREADS
9631 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
9632#else
9633 do {
Ronald Oussoren41761932020-11-08 10:05:27 +01009634#ifdef __APPLE__
9635/* This entire function will be removed from the module dict when the API
9636 * is not available.
9637 */
9638#pragma clang diagnostic push
9639#pragma clang diagnostic ignored "-Wunguarded-availability"
9640#pragma clang diagnostic ignored "-Wunguarded-availability-new"
9641#endif
Pablo Galindo4defba32018-01-27 16:16:37 +00009642 Py_BEGIN_ALLOW_THREADS
9643 _Py_BEGIN_SUPPRESS_IPH
9644 n = preadv(fd, iov, cnt, offset);
9645 _Py_END_SUPPRESS_IPH
9646 Py_END_ALLOW_THREADS
9647 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +01009648
9649#ifdef __APPLE__
9650#pragma clang diagnostic pop
9651#endif
9652
Pablo Galindo4defba32018-01-27 16:16:37 +00009653#endif
9654
9655 iov_cleanup(iov, buf, cnt);
9656 if (n < 0) {
9657 if (!async_err) {
9658 posix_error();
9659 }
9660 return -1;
9661 }
9662
9663 return n;
9664}
9665#endif /* HAVE_PREADV */
9666
Larry Hastings2f936352014-08-05 14:04:04 +10009667
9668/*[clinic input]
9669os.write -> Py_ssize_t
9670
9671 fd: int
9672 data: Py_buffer
9673 /
9674
9675Write a bytes object to a file descriptor.
9676[clinic start generated code]*/
9677
Larry Hastings2f936352014-08-05 14:04:04 +10009678static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009679os_write_impl(PyObject *module, int fd, Py_buffer *data)
9680/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009681{
Victor Stinner66aab0c2015-03-19 22:53:20 +01009682 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02009683}
9684
9685#ifdef HAVE_SENDFILE
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009686#ifdef __APPLE__
9687/*[clinic input]
9688os.sendfile
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009689
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009690 out_fd: int
9691 in_fd: int
9692 offset: Py_off_t
9693 count as sbytes: Py_off_t
9694 headers: object(c_default="NULL") = ()
9695 trailers: object(c_default="NULL") = ()
9696 flags: int = 0
9697
9698Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9699[clinic start generated code]*/
9700
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009701static PyObject *
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009702os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9703 Py_off_t sbytes, PyObject *headers, PyObject *trailers,
9704 int flags)
9705/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/
9706#elif defined(__FreeBSD__) || defined(__DragonFly__)
9707/*[clinic input]
9708os.sendfile
9709
9710 out_fd: int
9711 in_fd: int
9712 offset: Py_off_t
9713 count: Py_ssize_t
9714 headers: object(c_default="NULL") = ()
9715 trailers: object(c_default="NULL") = ()
9716 flags: int = 0
9717
9718Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9719[clinic start generated code]*/
9720
9721static PyObject *
9722os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset,
9723 Py_ssize_t count, PyObject *headers, PyObject *trailers,
9724 int flags)
9725/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/
9726#else
9727/*[clinic input]
9728os.sendfile
9729
9730 out_fd: int
9731 in_fd: int
9732 offset as offobj: object
9733 count: Py_ssize_t
9734
9735Copy count bytes from file descriptor in_fd to file descriptor out_fd.
9736[clinic start generated code]*/
9737
9738static PyObject *
9739os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
9740 Py_ssize_t count)
9741/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/
9742#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009743{
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009744 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009745 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009746
9747#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
9748#ifndef __APPLE__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009749 off_t sbytes;
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009750#endif
9751 Py_buffer *hbuf, *tbuf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009752 struct sf_hdtr sf;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009753
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02009754 sf.headers = NULL;
9755 sf.trailers = NULL;
9756
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009757 if (headers != NULL) {
9758 if (!PySequence_Check(headers)) {
9759 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009760 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009761 return NULL;
9762 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009763 Py_ssize_t i = PySequence_Size(headers);
9764 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009765 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009766 if (i > INT_MAX) {
9767 PyErr_SetString(PyExc_OverflowError,
9768 "sendfile() header is too large");
9769 return NULL;
9770 }
9771 if (i > 0) {
9772 sf.hdr_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009773 if (iov_setup(&(sf.headers), &hbuf,
9774 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009775 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009776#ifdef __APPLE__
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009777 for (i = 0; i < sf.hdr_cnt; i++) {
9778 Py_ssize_t blen = sf.headers[i].iov_len;
9779# define OFF_T_MAX 0x7fffffffffffffff
9780 if (sbytes >= OFF_T_MAX - blen) {
9781 PyErr_SetString(PyExc_OverflowError,
9782 "sendfile() header is too large");
9783 return NULL;
9784 }
9785 sbytes += blen;
9786 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00009787#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009788 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009789 }
9790 }
9791 if (trailers != NULL) {
9792 if (!PySequence_Check(trailers)) {
9793 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00009794 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009795 return NULL;
9796 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009797 Py_ssize_t i = PySequence_Size(trailers);
9798 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009799 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009800 if (i > INT_MAX) {
9801 PyErr_SetString(PyExc_OverflowError,
9802 "sendfile() trailer is too large");
9803 return NULL;
9804 }
9805 if (i > 0) {
9806 sf.trl_cnt = (int)i;
Serhiy Storchaka9d572732018-07-31 10:24:54 +03009807 if (iov_setup(&(sf.trailers), &tbuf,
9808 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009809 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03009810 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009811 }
9812 }
9813
Steve Dower8fc89802015-04-12 00:26:27 -04009814 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009815 do {
9816 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009817#ifdef __APPLE__
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009818 ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009819#else
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009820 ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009821#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009822 Py_END_ALLOW_THREADS
9823 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04009824 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009825
9826 if (sf.headers != NULL)
9827 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
9828 if (sf.trailers != NULL)
9829 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
9830
9831 if (ret < 0) {
9832 if ((errno == EAGAIN) || (errno == EBUSY)) {
9833 if (sbytes != 0) {
9834 // some data has been sent
9835 goto done;
9836 }
9837 else {
9838 // no data has been sent; upper application is supposed
9839 // to retry on EAGAIN or EBUSY
9840 return posix_error();
9841 }
9842 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009843 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009844 }
9845 goto done;
9846
9847done:
9848 #if !defined(HAVE_LARGEFILE_SUPPORT)
9849 return Py_BuildValue("l", sbytes);
9850 #else
9851 return Py_BuildValue("L", sbytes);
9852 #endif
9853
9854#else
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07009855#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009856 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009857 do {
9858 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009859 ret = sendfile(out_fd, in_fd, NULL, count);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009860 Py_END_ALLOW_THREADS
9861 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009862 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009863 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009864 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009865 }
9866#endif
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009867 off_t offset;
Larry Hastings2f936352014-08-05 14:04:04 +10009868 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00009869 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009870
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009871#if defined(__sun) && defined(__SVR4)
9872 // On Solaris, sendfile raises EINVAL rather than returning 0
9873 // when the offset is equal or bigger than the in_fd size.
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009874 struct stat st;
9875
9876 do {
9877 Py_BEGIN_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009878 ret = fstat(in_fd, &st);
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009879 Py_END_ALLOW_THREADS
Jakub Kulíkfa8c9e72020-09-09 21:29:42 +02009880 } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009881 if (ret < 0)
9882 return (!async_err) ? posix_error() : NULL;
9883
9884 if (offset >= st.st_size) {
9885 return Py_BuildValue("i", 0);
9886 }
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009887
9888 // On illumos specifically sendfile() may perform a partial write but
9889 // return -1/an error (in one confirmed case the destination socket
9890 // had a 5 second timeout set and errno was EAGAIN) and it's on the client
9891 // code to check if the offset parameter was modified by sendfile().
9892 //
9893 // We need this variable to track said change.
9894 off_t original_offset = offset;
Jakub Kulík8c0be6f2020-09-05 21:10:01 +02009895#endif
9896
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009897 do {
9898 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka2b560312020-04-18 19:14:10 +03009899 ret = sendfile(out_fd, in_fd, &offset, count);
Jakub Stasiakfd4ed572020-11-12 10:49:30 +01009900#if defined(__sun) && defined(__SVR4)
9901 // This handles illumos-specific sendfile() partial write behavior,
9902 // see a comment above for more details.
9903 if (ret < 0 && offset != original_offset) {
9904 ret = offset - original_offset;
9905 }
9906#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009907 Py_END_ALLOW_THREADS
9908 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009909 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009910 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00009911 return Py_BuildValue("n", ret);
9912#endif
9913}
Larry Hastings2f936352014-08-05 14:04:04 +10009914#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009915
Larry Hastings2f936352014-08-05 14:04:04 +10009916
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009917#if defined(__APPLE__)
9918/*[clinic input]
9919os._fcopyfile
9920
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009921 in_fd: int
9922 out_fd: int
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009923 flags: int
9924 /
9925
Giampaolo Rodolac7f02a92018-06-19 08:27:29 -07009926Efficiently copy content or metadata of 2 regular file descriptors (macOS).
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009927[clinic start generated code]*/
9928
9929static PyObject *
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009930os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags)
9931/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009932{
9933 int ret;
9934
9935 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka140a7d12019-10-13 11:59:31 +03009936 ret = fcopyfile(in_fd, out_fd, NULL, flags);
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +02009937 Py_END_ALLOW_THREADS
9938 if (ret < 0)
9939 return posix_error();
9940 Py_RETURN_NONE;
9941}
9942#endif
9943
9944
Larry Hastings2f936352014-08-05 14:04:04 +10009945/*[clinic input]
9946os.fstat
9947
9948 fd : int
9949
9950Perform a stat system call on the given file descriptor.
9951
9952Like stat(), but for an open file descriptor.
9953Equivalent to os.stat(fd).
9954[clinic start generated code]*/
9955
Larry Hastings2f936352014-08-05 14:04:04 +10009956static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009957os_fstat_impl(PyObject *module, int fd)
9958/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009959{
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 STRUCT_STAT st;
9961 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009962 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009963
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009964 do {
9965 Py_BEGIN_ALLOW_THREADS
9966 res = FSTAT(fd, &st);
9967 Py_END_ALLOW_THREADS
9968 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00009970#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01009971 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00009972#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009973 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00009974#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 }
Tim Peters5aa91602002-01-30 05:46:57 +00009976
Victor Stinner1c2fa782020-05-10 11:05:29 +02009977 return _pystat_fromstructstat(module, &st);
Guido van Rossum687dd131993-05-17 08:34:16 +00009978}
9979
Larry Hastings2f936352014-08-05 14:04:04 +10009980
9981/*[clinic input]
9982os.isatty -> bool
9983 fd: int
9984 /
9985
9986Return True if the fd is connected to a terminal.
9987
9988Return True if the file descriptor is an open file descriptor
9989connected to the slave end of a terminal.
9990[clinic start generated code]*/
9991
Larry Hastings2f936352014-08-05 14:04:04 +10009992static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009993os_isatty_impl(PyObject *module, int fd)
9994/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009995{
Steve Dower8fc89802015-04-12 00:26:27 -04009996 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04009997 _Py_BEGIN_SUPPRESS_IPH
9998 return_value = isatty(fd);
9999 _Py_END_SUPPRESS_IPH
10000 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100010001}
10002
10003
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010004#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +100010005/*[clinic input]
10006os.pipe
10007
10008Create a pipe.
10009
10010Returns a tuple of two file descriptors:
10011 (read_fd, write_fd)
10012[clinic start generated code]*/
10013
Larry Hastings2f936352014-08-05 14:04:04 +100010014static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010015os_pipe_impl(PyObject *module)
10016/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +000010017{
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +020010019#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010021 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010023#else
10024 int res;
10025#endif
10026
10027#ifdef MS_WINDOWS
10028 attr.nLength = sizeof(attr);
10029 attr.lpSecurityDescriptor = NULL;
10030 attr.bInheritHandle = FALSE;
10031
10032 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -080010033 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +020010034 ok = CreatePipe(&read, &write, &attr, 0);
10035 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -070010036 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
10037 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010038 if (fds[0] == -1 || fds[1] == -1) {
10039 CloseHandle(read);
10040 CloseHandle(write);
10041 ok = 0;
10042 }
10043 }
Steve Dowerc3630612016-11-19 18:41:16 -080010044 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +020010045 Py_END_ALLOW_THREADS
10046
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +010010048 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +020010049#else
10050
10051#ifdef HAVE_PIPE2
10052 Py_BEGIN_ALLOW_THREADS
10053 res = pipe2(fds, O_CLOEXEC);
10054 Py_END_ALLOW_THREADS
10055
10056 if (res != 0 && errno == ENOSYS)
10057 {
10058#endif
10059 Py_BEGIN_ALLOW_THREADS
10060 res = pipe(fds);
10061 Py_END_ALLOW_THREADS
10062
10063 if (res == 0) {
10064 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
10065 close(fds[0]);
10066 close(fds[1]);
10067 return NULL;
10068 }
10069 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
10070 close(fds[0]);
10071 close(fds[1]);
10072 return NULL;
10073 }
10074 }
10075#ifdef HAVE_PIPE2
10076 }
10077#endif
10078
10079 if (res != 0)
10080 return PyErr_SetFromErrno(PyExc_OSError);
10081#endif /* !MS_WINDOWS */
10082 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +000010083}
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010084#endif /* HAVE_PIPE */
10085
Larry Hastings2f936352014-08-05 14:04:04 +100010086
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010087#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +100010088/*[clinic input]
10089os.pipe2
10090
10091 flags: int
10092 /
10093
10094Create a pipe with flags set atomically.
10095
10096Returns a tuple of two file descriptors:
10097 (read_fd, write_fd)
10098
10099flags can be constructed by ORing together one or more of these values:
10100O_NONBLOCK, O_CLOEXEC.
10101[clinic start generated code]*/
10102
Larry Hastings2f936352014-08-05 14:04:04 +100010103static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010104os_pipe2_impl(PyObject *module, int flags)
10105/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010106{
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010107 int fds[2];
10108 int res;
10109
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010110 res = pipe2(fds, flags);
10111 if (res != 0)
10112 return posix_error();
10113 return Py_BuildValue("(ii)", fds[0], fds[1]);
10114}
10115#endif /* HAVE_PIPE2 */
10116
Larry Hastings2f936352014-08-05 14:04:04 +100010117
Ross Lagerwall7807c352011-03-17 20:20:30 +020010118#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +100010119/*[clinic input]
10120os.writev -> Py_ssize_t
10121 fd: int
10122 buffers: object
10123 /
10124
10125Iterate over buffers, and write the contents of each to a file descriptor.
10126
10127Returns the total number of bytes written.
10128buffers must be a sequence of bytes-like objects.
10129[clinic start generated code]*/
10130
Larry Hastings2f936352014-08-05 14:04:04 +100010131static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010132os_writev_impl(PyObject *module, int fd, PyObject *buffers)
10133/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010134{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010135 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +100010136 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010137 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010138 struct iovec *iov;
10139 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +100010140
10141 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020010142 PyErr_SetString(PyExc_TypeError,
10143 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +100010144 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010145 }
Larry Hastings2f936352014-08-05 14:04:04 +100010146 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +030010147 if (cnt < 0)
10148 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010149
Larry Hastings2f936352014-08-05 14:04:04 +100010150 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10151 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010152 }
10153
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010154 do {
10155 Py_BEGIN_ALLOW_THREADS
10156 result = writev(fd, iov, cnt);
10157 Py_END_ALLOW_THREADS
10158 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +020010159
10160 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010161 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010162 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +010010163
Georg Brandl306336b2012-06-24 12:55:33 +020010164 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010165}
Larry Hastings2f936352014-08-05 14:04:04 +100010166#endif /* HAVE_WRITEV */
10167
10168
10169#ifdef HAVE_PWRITE
10170/*[clinic input]
10171os.pwrite -> Py_ssize_t
10172
10173 fd: int
10174 buffer: Py_buffer
10175 offset: Py_off_t
10176 /
10177
10178Write bytes to a file descriptor starting at a particular offset.
10179
10180Write buffer to fd, starting at offset bytes from the beginning of
10181the file. Returns the number of bytes writte. Does not change the
10182current file offset.
10183[clinic start generated code]*/
10184
Larry Hastings2f936352014-08-05 14:04:04 +100010185static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010186os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
10187/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010188{
10189 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010190 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010191
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010192 do {
10193 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -040010194 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010195 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -040010196 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010197 Py_END_ALLOW_THREADS
10198 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100010199
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010200 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +100010201 posix_error();
10202 return size;
10203}
10204#endif /* HAVE_PWRITE */
10205
Pablo Galindo4defba32018-01-27 16:16:37 +000010206#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
10207/*[clinic input]
10208os.pwritev -> Py_ssize_t
10209
10210 fd: int
10211 buffers: object
10212 offset: Py_off_t
10213 flags: int = 0
10214 /
10215
10216Writes the contents of bytes-like objects to a file descriptor at a given offset.
10217
10218Combines the functionality of writev() and pwrite(). All buffers must be a sequence
10219of bytes-like objects. Buffers are processed in array order. Entire contents of first
10220buffer is written before proceeding to second, and so on. The operating system may
10221set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
10222This function writes the contents of each object to the file descriptor and returns
10223the total number of bytes written.
10224
10225The flags argument contains a bitwise OR of zero or more of the following flags:
10226
10227- RWF_DSYNC
10228- RWF_SYNC
YoSTEALTH76ef2552020-05-27 15:32:22 -060010229- RWF_APPEND
Pablo Galindo4defba32018-01-27 16:16:37 +000010230
10231Using non-zero flags requires Linux 4.7 or newer.
10232[clinic start generated code]*/
10233
10234static Py_ssize_t
10235os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
10236 int flags)
YoSTEALTH76ef2552020-05-27 15:32:22 -060010237/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=35358c327e1a2a8e]*/
Pablo Galindo4defba32018-01-27 16:16:37 +000010238{
10239 Py_ssize_t cnt;
10240 Py_ssize_t result;
10241 int async_err = 0;
10242 struct iovec *iov;
10243 Py_buffer *buf;
10244
10245 if (!PySequence_Check(buffers)) {
10246 PyErr_SetString(PyExc_TypeError,
10247 "pwritev() arg 2 must be a sequence");
10248 return -1;
10249 }
10250
10251 cnt = PySequence_Size(buffers);
10252 if (cnt < 0) {
10253 return -1;
10254 }
10255
10256#ifndef HAVE_PWRITEV2
10257 if(flags != 0) {
10258 argument_unavailable_error("pwritev2", "flags");
10259 return -1;
10260 }
10261#endif
10262
10263 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
10264 return -1;
10265 }
10266#ifdef HAVE_PWRITEV2
10267 do {
10268 Py_BEGIN_ALLOW_THREADS
10269 _Py_BEGIN_SUPPRESS_IPH
10270 result = pwritev2(fd, iov, cnt, offset, flags);
10271 _Py_END_SUPPRESS_IPH
10272 Py_END_ALLOW_THREADS
10273 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10274#else
Ronald Oussoren41761932020-11-08 10:05:27 +010010275
10276#ifdef __APPLE__
10277/* This entire function will be removed from the module dict when the API
10278 * is not available.
10279 */
10280#pragma clang diagnostic push
10281#pragma clang diagnostic ignored "-Wunguarded-availability"
10282#pragma clang diagnostic ignored "-Wunguarded-availability-new"
10283#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000010284 do {
10285 Py_BEGIN_ALLOW_THREADS
10286 _Py_BEGIN_SUPPRESS_IPH
10287 result = pwritev(fd, iov, cnt, offset);
10288 _Py_END_SUPPRESS_IPH
10289 Py_END_ALLOW_THREADS
10290 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ronald Oussoren41761932020-11-08 10:05:27 +010010291
10292#ifdef __APPLE__
10293#pragma clang diagnostic pop
10294#endif
10295
Pablo Galindo4defba32018-01-27 16:16:37 +000010296#endif
10297
10298 iov_cleanup(iov, buf, cnt);
10299 if (result < 0) {
10300 if (!async_err) {
10301 posix_error();
10302 }
10303 return -1;
10304 }
10305
10306 return result;
10307}
10308#endif /* HAVE_PWRITEV */
10309
Pablo Galindoaac4d032019-05-31 19:39:47 +010010310#ifdef HAVE_COPY_FILE_RANGE
10311/*[clinic input]
10312
10313os.copy_file_range
10314 src: int
10315 Source file descriptor.
10316 dst: int
10317 Destination file descriptor.
10318 count: Py_ssize_t
10319 Number of bytes to copy.
10320 offset_src: object = None
10321 Starting offset in src.
10322 offset_dst: object = None
10323 Starting offset in dst.
10324
10325Copy count bytes from one file descriptor to another.
10326
10327If offset_src is None, then src is read from the current position;
10328respectively for offset_dst.
10329[clinic start generated code]*/
10330
10331static PyObject *
10332os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10333 PyObject *offset_src, PyObject *offset_dst)
10334/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/
10335{
10336 off_t offset_src_val, offset_dst_val;
10337 off_t *p_offset_src = NULL;
10338 off_t *p_offset_dst = NULL;
10339 Py_ssize_t ret;
10340 int async_err = 0;
10341 /* The flags argument is provided to allow
10342 * for future extensions and currently must be to 0. */
10343 int flags = 0;
Pablo Galindo4defba32018-01-27 16:16:37 +000010344
10345
Pablo Galindoaac4d032019-05-31 19:39:47 +010010346 if (count < 0) {
10347 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10348 return NULL;
10349 }
10350
10351 if (offset_src != Py_None) {
10352 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10353 return NULL;
10354 }
10355 p_offset_src = &offset_src_val;
10356 }
10357
10358 if (offset_dst != Py_None) {
10359 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10360 return NULL;
10361 }
10362 p_offset_dst = &offset_dst_val;
10363 }
10364
10365 do {
10366 Py_BEGIN_ALLOW_THREADS
10367 ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags);
10368 Py_END_ALLOW_THREADS
10369 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10370
10371 if (ret < 0) {
10372 return (!async_err) ? posix_error() : NULL;
10373 }
10374
10375 return PyLong_FromSsize_t(ret);
10376}
10377#endif /* HAVE_COPY_FILE_RANGE*/
Larry Hastings2f936352014-08-05 14:04:04 +100010378
Pablo Galindodedc2cd2020-12-02 17:57:18 +000010379#if (defined(HAVE_SPLICE) && !defined(_AIX))
Pablo Galindoa57b3d32020-11-17 00:00:38 +000010380/*[clinic input]
10381
10382os.splice
10383 src: int
10384 Source file descriptor.
10385 dst: int
10386 Destination file descriptor.
10387 count: Py_ssize_t
10388 Number of bytes to copy.
10389 offset_src: object = None
10390 Starting offset in src.
10391 offset_dst: object = None
10392 Starting offset in dst.
10393 flags: unsigned_int = 0
10394 Flags to modify the semantics of the call.
10395
10396Transfer count bytes from one pipe to a descriptor or vice versa.
10397
10398If offset_src is None, then src is read from the current position;
10399respectively for offset_dst. The offset associated to the file
10400descriptor that refers to a pipe must be None.
10401[clinic start generated code]*/
10402
10403static PyObject *
10404os_splice_impl(PyObject *module, int src, int dst, Py_ssize_t count,
10405 PyObject *offset_src, PyObject *offset_dst,
10406 unsigned int flags)
10407/*[clinic end generated code: output=d0386f25a8519dc5 input=047527c66c6d2e0a]*/
10408{
10409 off_t offset_src_val, offset_dst_val;
10410 off_t *p_offset_src = NULL;
10411 off_t *p_offset_dst = NULL;
10412 Py_ssize_t ret;
10413 int async_err = 0;
10414
10415 if (count < 0) {
10416 PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed");
10417 return NULL;
10418 }
10419
10420 if (offset_src != Py_None) {
10421 if (!Py_off_t_converter(offset_src, &offset_src_val)) {
10422 return NULL;
10423 }
10424 p_offset_src = &offset_src_val;
10425 }
10426
10427 if (offset_dst != Py_None) {
10428 if (!Py_off_t_converter(offset_dst, &offset_dst_val)) {
10429 return NULL;
10430 }
10431 p_offset_dst = &offset_dst_val;
10432 }
10433
10434 do {
10435 Py_BEGIN_ALLOW_THREADS
10436 ret = splice(src, p_offset_src, dst, p_offset_dst, count, flags);
10437 Py_END_ALLOW_THREADS
10438 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
10439
10440 if (ret < 0) {
10441 return (!async_err) ? posix_error() : NULL;
10442 }
10443
10444 return PyLong_FromSsize_t(ret);
10445}
10446#endif /* HAVE_SPLICE*/
10447
Larry Hastings2f936352014-08-05 14:04:04 +100010448#ifdef HAVE_MKFIFO
10449/*[clinic input]
10450os.mkfifo
10451
10452 path: path_t
10453 mode: int=0o666
10454 *
10455 dir_fd: dir_fd(requires='mkfifoat')=None
10456
10457Create a "fifo" (a POSIX named pipe).
10458
10459If dir_fd is not None, it should be a file descriptor open to a directory,
10460 and path should be relative; path will then be relative to that directory.
10461dir_fd may not be implemented on your platform.
10462 If it is unavailable, using it will raise a NotImplementedError.
10463[clinic start generated code]*/
10464
Larry Hastings2f936352014-08-05 14:04:04 +100010465static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010466os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
10467/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010468{
10469 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010470 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010471
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010472 do {
10473 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010474#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010475 if (dir_fd != DEFAULT_DIR_FD)
10476 result = mkfifoat(dir_fd, path->narrow, mode);
10477 else
Ross Lagerwall7807c352011-03-17 20:20:30 +020010478#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010479 result = mkfifo(path->narrow, mode);
10480 Py_END_ALLOW_THREADS
10481 } while (result != 0 && errno == EINTR &&
10482 !(async_err = PyErr_CheckSignals()));
10483 if (result != 0)
10484 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010485
10486 Py_RETURN_NONE;
10487}
10488#endif /* HAVE_MKFIFO */
10489
10490
10491#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
10492/*[clinic input]
10493os.mknod
10494
10495 path: path_t
10496 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010497 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +100010498 *
10499 dir_fd: dir_fd(requires='mknodat')=None
10500
10501Create a node in the file system.
10502
10503Create a node in the file system (file, device special file or named pipe)
10504at path. mode specifies both the permissions to use and the
10505type of node to be created, being combined (bitwise OR) with one of
10506S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
10507device defines the newly created device special file (probably using
10508os.makedev()). Otherwise device is ignored.
10509
10510If dir_fd is not None, it should be a file descriptor open to a directory,
10511 and path should be relative; path will then be relative to that directory.
10512dir_fd may not be implemented on your platform.
10513 If it is unavailable, using it will raise a NotImplementedError.
10514[clinic start generated code]*/
10515
Larry Hastings2f936352014-08-05 14:04:04 +100010516static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010517os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -040010518 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010519/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010520{
10521 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010522 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010523
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010524 do {
10525 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +100010526#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010527 if (dir_fd != DEFAULT_DIR_FD)
10528 result = mknodat(dir_fd, path->narrow, mode, device);
10529 else
Larry Hastings2f936352014-08-05 14:04:04 +100010530#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010531 result = mknod(path->narrow, mode, device);
10532 Py_END_ALLOW_THREADS
10533 } while (result != 0 && errno == EINTR &&
10534 !(async_err = PyErr_CheckSignals()));
10535 if (result != 0)
10536 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010537
10538 Py_RETURN_NONE;
10539}
10540#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
10541
10542
10543#ifdef HAVE_DEVICE_MACROS
10544/*[clinic input]
10545os.major -> unsigned_int
10546
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010547 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010548 /
10549
10550Extracts a device major number from a raw device number.
10551[clinic start generated code]*/
10552
Larry Hastings2f936352014-08-05 14:04:04 +100010553static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010554os_major_impl(PyObject *module, dev_t device)
10555/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010556{
10557 return major(device);
10558}
10559
10560
10561/*[clinic input]
10562os.minor -> unsigned_int
10563
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010564 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010565 /
10566
10567Extracts a device minor number from a raw device number.
10568[clinic start generated code]*/
10569
Larry Hastings2f936352014-08-05 14:04:04 +100010570static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010571os_minor_impl(PyObject *module, dev_t device)
10572/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010573{
10574 return minor(device);
10575}
10576
10577
10578/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010579os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +100010580
10581 major: int
10582 minor: int
10583 /
10584
10585Composes a raw device number from the major and minor device numbers.
10586[clinic start generated code]*/
10587
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +020010588static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010589os_makedev_impl(PyObject *module, int major, int minor)
10590/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010591{
10592 return makedev(major, minor);
10593}
10594#endif /* HAVE_DEVICE_MACROS */
10595
10596
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010597#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010598/*[clinic input]
10599os.ftruncate
10600
10601 fd: int
10602 length: Py_off_t
10603 /
10604
10605Truncate a file, specified by file descriptor, to a specific length.
10606[clinic start generated code]*/
10607
Larry Hastings2f936352014-08-05 14:04:04 +100010608static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010609os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
10610/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010611{
10612 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010613 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +100010614
Steve Dowerb82e17e2019-05-23 08:45:22 -070010615 if (PySys_Audit("os.truncate", "in", fd, length) < 0) {
10616 return NULL;
10617 }
10618
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010619 do {
10620 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010621 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010622#ifdef MS_WINDOWS
10623 result = _chsize_s(fd, length);
10624#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010625 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010626#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010627 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010628 Py_END_ALLOW_THREADS
10629 } while (result != 0 && errno == EINTR &&
10630 !(async_err = PyErr_CheckSignals()));
10631 if (result != 0)
10632 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010633 Py_RETURN_NONE;
10634}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010635#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010636
10637
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010638#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010639/*[clinic input]
10640os.truncate
10641 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
10642 length: Py_off_t
10643
10644Truncate a file, specified by path, to a specific length.
10645
10646On some platforms, path may also be specified as an open file descriptor.
10647 If this functionality is unavailable, using it raises an exception.
10648[clinic start generated code]*/
10649
Larry Hastings2f936352014-08-05 14:04:04 +100010650static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010651os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
10652/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010653{
10654 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010655#ifdef MS_WINDOWS
10656 int fd;
10657#endif
10658
10659 if (path->fd != -1)
10660 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010661
Steve Dowerb82e17e2019-05-23 08:45:22 -070010662 if (PySys_Audit("os.truncate", "On", path->object, length) < 0) {
10663 return NULL;
10664 }
10665
Larry Hastings2f936352014-08-05 14:04:04 +100010666 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -040010667 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010668#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070010669 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +020010670 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010671 result = -1;
10672 else {
10673 result = _chsize_s(fd, length);
10674 close(fd);
10675 if (result < 0)
10676 errno = result;
10677 }
10678#else
10679 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +100010680#endif
Steve Dowera1c7e722015-04-12 00:26:43 -040010681 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +100010682 Py_END_ALLOW_THREADS
10683 if (result < 0)
Alexey Izbyshev83460312018-10-20 03:28:22 +030010684 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +100010685
10686 Py_RETURN_NONE;
10687}
Steve Dowerfe0a41a2015-03-20 19:50:46 -070010688#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +100010689
Ross Lagerwall7807c352011-03-17 20:20:30 +020010690
Victor Stinnerd6b17692014-09-30 12:20:05 +020010691/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
10692 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
10693 defined, which is the case in Python on AIX. AIX bug report:
10694 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
10695#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
10696# define POSIX_FADVISE_AIX_BUG
10697#endif
10698
Victor Stinnerec39e262014-09-30 12:35:58 +020010699
Victor Stinnerd6b17692014-09-30 12:20:05 +020010700#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010701/*[clinic input]
10702os.posix_fallocate
10703
10704 fd: int
10705 offset: Py_off_t
10706 length: Py_off_t
10707 /
10708
10709Ensure a file has allocated at least a particular number of bytes on disk.
10710
10711Ensure that the file specified by fd encompasses a range of bytes
10712starting at offset bytes from the beginning and continuing for length bytes.
10713[clinic start generated code]*/
10714
Larry Hastings2f936352014-08-05 14:04:04 +100010715static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010716os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010717 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010718/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010719{
10720 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010721 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010722
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010723 do {
10724 Py_BEGIN_ALLOW_THREADS
10725 result = posix_fallocate(fd, offset, length);
10726 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010727 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10728
10729 if (result == 0)
10730 Py_RETURN_NONE;
10731
10732 if (async_err)
10733 return NULL;
10734
10735 errno = result;
10736 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010737}
Victor Stinnerec39e262014-09-30 12:35:58 +020010738#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +100010739
Ross Lagerwall7807c352011-03-17 20:20:30 +020010740
Victor Stinnerd6b17692014-09-30 12:20:05 +020010741#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +100010742/*[clinic input]
10743os.posix_fadvise
10744
10745 fd: int
10746 offset: Py_off_t
10747 length: Py_off_t
10748 advice: int
10749 /
10750
10751Announce an intention to access data in a specific pattern.
10752
10753Announce an intention to access data in a specific pattern, thus allowing
10754the kernel to make optimizations.
10755The advice applies to the region of the file specified by fd starting at
10756offset and continuing for length bytes.
10757advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
10758POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
10759POSIX_FADV_DONTNEED.
10760[clinic start generated code]*/
10761
Larry Hastings2f936352014-08-05 14:04:04 +100010762static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010763os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -040010764 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010765/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010766{
10767 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010768 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +020010769
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000010770 do {
10771 Py_BEGIN_ALLOW_THREADS
10772 result = posix_fadvise(fd, offset, length, advice);
10773 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +050010774 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
10775
10776 if (result == 0)
10777 Py_RETURN_NONE;
10778
10779 if (async_err)
10780 return NULL;
10781
10782 errno = result;
10783 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +020010784}
Victor Stinnerec39e262014-09-30 12:35:58 +020010785#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010786
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000010787
Thomas Hellerf78f12a2007-11-08 19:33:05 +000010788#ifdef MS_WINDOWS
Victor Stinner161e7b32020-01-24 11:53:44 +010010789static PyObject*
10790win32_putenv(PyObject *name, PyObject *value)
10791{
10792 /* Search from index 1 because on Windows starting '=' is allowed for
10793 defining hidden environment variables. */
10794 if (PyUnicode_GET_LENGTH(name) == 0 ||
10795 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
10796 {
10797 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10798 return NULL;
10799 }
10800 PyObject *unicode;
10801 if (value != NULL) {
10802 unicode = PyUnicode_FromFormat("%U=%U", name, value);
10803 }
10804 else {
10805 unicode = PyUnicode_FromFormat("%U=", name);
10806 }
10807 if (unicode == NULL) {
10808 return NULL;
10809 }
10810
10811 Py_ssize_t size;
10812 /* PyUnicode_AsWideCharString() rejects embedded null characters */
10813 wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
10814 Py_DECREF(unicode);
10815
10816 if (env == NULL) {
10817 return NULL;
10818 }
10819 if (size > _MAX_ENV) {
10820 PyErr_Format(PyExc_ValueError,
10821 "the environment variable is longer than %u characters",
10822 _MAX_ENV);
10823 PyMem_Free(env);
10824 return NULL;
10825 }
10826
10827 /* _wputenv() and SetEnvironmentVariableW() update the environment in the
10828 Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
10829 and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
10830
10831 Prefer _wputenv() to be compatible with C libraries using CRT
10832 variables and CRT functions using these variables (ex: getenv()). */
10833 int err = _wputenv(env);
10834 PyMem_Free(env);
10835
10836 if (err) {
10837 posix_error();
10838 return NULL;
10839 }
10840
10841 Py_RETURN_NONE;
10842}
10843#endif
10844
10845
10846#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010847/*[clinic input]
10848os.putenv
10849
10850 name: unicode
10851 value: unicode
10852 /
10853
10854Change or add an environment variable.
10855[clinic start generated code]*/
10856
Larry Hastings2f936352014-08-05 14:04:04 +100010857static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010858os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10859/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010860{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010861 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10862 return NULL;
10863 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010864 return win32_putenv(name, value);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010865}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010866#else
Larry Hastings2f936352014-08-05 14:04:04 +100010867/*[clinic input]
10868os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +000010869
Larry Hastings2f936352014-08-05 14:04:04 +100010870 name: FSConverter
10871 value: FSConverter
10872 /
10873
10874Change or add an environment variable.
10875[clinic start generated code]*/
10876
Larry Hastings2f936352014-08-05 14:04:04 +100010877static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010878os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
10879/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010880{
Serhiy Storchaka77703942017-06-25 07:33:01 +030010881 const char *name_string = PyBytes_AS_STRING(name);
10882 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +100010883
Serhiy Storchaka77703942017-06-25 07:33:01 +030010884 if (strchr(name_string, '=') != NULL) {
10885 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
10886 return NULL;
10887 }
Victor Stinnerb477d192020-01-22 22:48:16 +010010888
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010889 if (PySys_Audit("os.putenv", "OO", name, value) < 0) {
10890 return NULL;
10891 }
10892
Victor Stinnerb477d192020-01-22 22:48:16 +010010893 if (setenv(name_string, value_string, 1)) {
10894 return posix_error();
10895 }
Larry Hastings2f936352014-08-05 14:04:04 +100010896 Py_RETURN_NONE;
10897}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010898#endif /* !defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100010899
10900
Victor Stinner161e7b32020-01-24 11:53:44 +010010901#ifdef MS_WINDOWS
10902/*[clinic input]
10903os.unsetenv
10904 name: unicode
10905 /
10906
10907Delete an environment variable.
10908[clinic start generated code]*/
10909
10910static PyObject *
10911os_unsetenv_impl(PyObject *module, PyObject *name)
10912/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
10913{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010914 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10915 return NULL;
10916 }
Victor Stinner161e7b32020-01-24 11:53:44 +010010917 return win32_putenv(name, NULL);
10918}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010919#else
Larry Hastings2f936352014-08-05 14:04:04 +100010920/*[clinic input]
10921os.unsetenv
10922 name: FSConverter
10923 /
10924
10925Delete an environment variable.
10926[clinic start generated code]*/
10927
Larry Hastings2f936352014-08-05 14:04:04 +100010928static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010929os_unsetenv_impl(PyObject *module, PyObject *name)
10930/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010931{
Saiyang Gou7514f4f2020-02-12 23:47:42 -080010932 if (PySys_Audit("os.unsetenv", "(O)", name) < 0) {
10933 return NULL;
10934 }
Victor Stinner984890f2011-11-24 13:53:38 +010010935#ifdef HAVE_BROKEN_UNSETENV
10936 unsetenv(PyBytes_AS_STRING(name));
10937#else
Victor Stinner161e7b32020-01-24 11:53:44 +010010938 int err = unsetenv(PyBytes_AS_STRING(name));
10939 if (err) {
Victor Stinner60b385e2011-11-22 22:01:28 +010010940 return posix_error();
Victor Stinner161e7b32020-01-24 11:53:44 +010010941 }
Victor Stinner984890f2011-11-24 13:53:38 +010010942#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010943
Victor Stinner84ae1182010-05-06 22:05:07 +000010944 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +000010945}
Victor Stinnerb8d12622020-01-24 14:05:48 +010010946#endif /* !MS_WINDOWS */
Guido van Rossumc524d952001-10-19 01:31:59 +000010947
Larry Hastings2f936352014-08-05 14:04:04 +100010948
10949/*[clinic input]
10950os.strerror
10951
10952 code: int
10953 /
10954
10955Translate an error code to a message string.
10956[clinic start generated code]*/
10957
Larry Hastings2f936352014-08-05 14:04:04 +100010958static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010959os_strerror_impl(PyObject *module, int code)
10960/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010961{
10962 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +000010963 if (message == NULL) {
10964 PyErr_SetString(PyExc_ValueError,
10965 "strerror() argument out of range");
10966 return NULL;
10967 }
Victor Stinner1b579672011-12-17 05:47:23 +010010968 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +000010969}
Guido van Rossumb6a47161997-09-15 22:54:34 +000010970
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010971
Guido van Rossumc9641791998-08-04 15:26:23 +000010972#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010973#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +100010974/*[clinic input]
10975os.WCOREDUMP -> bool
10976
10977 status: int
10978 /
10979
10980Return True if the process returning status was dumped to a core file.
10981[clinic start generated code]*/
10982
Larry Hastings2f936352014-08-05 14:04:04 +100010983static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010984os_WCOREDUMP_impl(PyObject *module, int status)
10985/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010986{
10987 WAIT_TYPE wait_status;
10988 WAIT_STATUS_INT(wait_status) = status;
10989 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000010990}
10991#endif /* WCOREDUMP */
10992
Larry Hastings2f936352014-08-05 14:04:04 +100010993
Fred Drake106c1a02002-04-23 15:58:02 +000010994#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +100010995/*[clinic input]
10996os.WIFCONTINUED -> bool
10997
10998 status: int
10999
11000Return True if a particular process was continued from a job control stop.
11001
11002Return True if the process returning status was continued from a
11003job control stop.
11004[clinic start generated code]*/
11005
Larry Hastings2f936352014-08-05 14:04:04 +100011006static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011007os_WIFCONTINUED_impl(PyObject *module, int status)
11008/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011009{
11010 WAIT_TYPE wait_status;
11011 WAIT_STATUS_INT(wait_status) = status;
11012 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +000011013}
11014#endif /* WIFCONTINUED */
11015
Larry Hastings2f936352014-08-05 14:04:04 +100011016
Guido van Rossumc9641791998-08-04 15:26:23 +000011017#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +100011018/*[clinic input]
11019os.WIFSTOPPED -> bool
11020
11021 status: int
11022
11023Return True if the process returning status was stopped.
11024[clinic start generated code]*/
11025
Larry Hastings2f936352014-08-05 14:04:04 +100011026static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011027os_WIFSTOPPED_impl(PyObject *module, int status)
11028/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011029{
11030 WAIT_TYPE wait_status;
11031 WAIT_STATUS_INT(wait_status) = status;
11032 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011033}
11034#endif /* WIFSTOPPED */
11035
Larry Hastings2f936352014-08-05 14:04:04 +100011036
Guido van Rossumc9641791998-08-04 15:26:23 +000011037#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +100011038/*[clinic input]
11039os.WIFSIGNALED -> bool
11040
11041 status: int
11042
11043Return True if the process returning status was terminated by a signal.
11044[clinic start generated code]*/
11045
Larry Hastings2f936352014-08-05 14:04:04 +100011046static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011047os_WIFSIGNALED_impl(PyObject *module, int status)
11048/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011049{
11050 WAIT_TYPE wait_status;
11051 WAIT_STATUS_INT(wait_status) = status;
11052 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011053}
11054#endif /* WIFSIGNALED */
11055
Larry Hastings2f936352014-08-05 14:04:04 +100011056
Guido van Rossumc9641791998-08-04 15:26:23 +000011057#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +100011058/*[clinic input]
11059os.WIFEXITED -> bool
11060
11061 status: int
11062
11063Return True if the process returning status exited via the exit() system call.
11064[clinic start generated code]*/
11065
Larry Hastings2f936352014-08-05 14:04:04 +100011066static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011067os_WIFEXITED_impl(PyObject *module, int status)
11068/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011069{
11070 WAIT_TYPE wait_status;
11071 WAIT_STATUS_INT(wait_status) = status;
11072 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011073}
11074#endif /* WIFEXITED */
11075
Larry Hastings2f936352014-08-05 14:04:04 +100011076
Guido van Rossum54ecc3d1999-01-27 17:53:11 +000011077#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +100011078/*[clinic input]
11079os.WEXITSTATUS -> int
11080
11081 status: int
11082
11083Return the process return code from status.
11084[clinic start generated code]*/
11085
Larry Hastings2f936352014-08-05 14:04:04 +100011086static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011087os_WEXITSTATUS_impl(PyObject *module, int status)
11088/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011089{
11090 WAIT_TYPE wait_status;
11091 WAIT_STATUS_INT(wait_status) = status;
11092 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011093}
11094#endif /* WEXITSTATUS */
11095
Larry Hastings2f936352014-08-05 14:04:04 +100011096
Guido van Rossumc9641791998-08-04 15:26:23 +000011097#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011098/*[clinic input]
11099os.WTERMSIG -> int
11100
11101 status: int
11102
11103Return the signal that terminated the process that provided the status value.
11104[clinic start generated code]*/
11105
Larry Hastings2f936352014-08-05 14:04:04 +100011106static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011107os_WTERMSIG_impl(PyObject *module, int status)
11108/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011109{
11110 WAIT_TYPE wait_status;
11111 WAIT_STATUS_INT(wait_status) = status;
11112 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011113}
11114#endif /* WTERMSIG */
11115
Larry Hastings2f936352014-08-05 14:04:04 +100011116
Guido van Rossumc9641791998-08-04 15:26:23 +000011117#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +100011118/*[clinic input]
11119os.WSTOPSIG -> int
11120
11121 status: int
11122
11123Return the signal that stopped the process that provided the status value.
11124[clinic start generated code]*/
11125
Larry Hastings2f936352014-08-05 14:04:04 +100011126static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011127os_WSTOPSIG_impl(PyObject *module, int status)
11128/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011129{
11130 WAIT_TYPE wait_status;
11131 WAIT_STATUS_INT(wait_status) = status;
11132 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +000011133}
11134#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +000011135#endif /* HAVE_SYS_WAIT_H */
11136
11137
Thomas Wouters477c8d52006-05-27 19:21:47 +000011138#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +000011139#ifdef _SCO_DS
11140/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
11141 needed definitions in sys/statvfs.h */
11142#define _SVID3
11143#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011144#include <sys/statvfs.h>
11145
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011146static PyObject*
Victor Stinner1c2fa782020-05-10 11:05:29 +020011147_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) {
11148 PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080011149 PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011150 if (v == NULL)
11151 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011152
11153#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11155 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11156 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
11157 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
11158 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
11159 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
11160 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
11161 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
11162 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11163 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011164#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011165 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
11166 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
11167 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011168 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011170 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011171 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011172 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011174 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011176 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +000011177 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011178 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
11180 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011181#endif
Michael Felt502d5512018-01-05 13:01:58 +010011182/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
11183 * (issue #32390). */
11184#if defined(_AIX) && defined(_ALL_SOURCE)
11185 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
11186#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +010011187 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +010011188#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +010011189 if (PyErr_Occurred()) {
11190 Py_DECREF(v);
11191 return NULL;
11192 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011193
Victor Stinner8c62be82010-05-06 00:08:46 +000011194 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011195}
11196
Larry Hastings2f936352014-08-05 14:04:04 +100011197
11198/*[clinic input]
11199os.fstatvfs
11200 fd: int
11201 /
11202
11203Perform an fstatvfs system call on the given fd.
11204
11205Equivalent to statvfs(fd).
11206[clinic start generated code]*/
11207
Larry Hastings2f936352014-08-05 14:04:04 +100011208static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011209os_fstatvfs_impl(PyObject *module, int fd)
11210/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011211{
11212 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011213 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011215
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011216 do {
11217 Py_BEGIN_ALLOW_THREADS
11218 result = fstatvfs(fd, &st);
11219 Py_END_ALLOW_THREADS
11220 } while (result != 0 && errno == EINTR &&
11221 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +100011222 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +000011223 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011224
Victor Stinner1c2fa782020-05-10 11:05:29 +020011225 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011226}
Larry Hastings2f936352014-08-05 14:04:04 +100011227#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +000011228
11229
Thomas Wouters477c8d52006-05-27 19:21:47 +000011230#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +000011231#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +100011232/*[clinic input]
11233os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +000011234
Larry Hastings2f936352014-08-05 14:04:04 +100011235 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
11236
11237Perform a statvfs system call on the given path.
11238
11239path may always be specified as a string.
11240On some platforms, path may also be specified as an open file descriptor.
11241 If this functionality is unavailable, using it raises an exception.
11242[clinic start generated code]*/
11243
Larry Hastings2f936352014-08-05 14:04:04 +100011244static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011245os_statvfs_impl(PyObject *module, path_t *path)
11246/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011247{
11248 int result;
11249 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011250
11251 Py_BEGIN_ALLOW_THREADS
11252#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +100011253 if (path->fd != -1) {
Larry Hastings2f936352014-08-05 14:04:04 +100011254 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011255 }
11256 else
11257#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011258 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011259 Py_END_ALLOW_THREADS
11260
11261 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011262 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011263 }
11264
Victor Stinner1c2fa782020-05-10 11:05:29 +020011265 return _pystatvfs_fromstructstatvfs(module, st);
Guido van Rossum94f6f721999-01-06 18:42:14 +000011266}
Larry Hastings2f936352014-08-05 14:04:04 +100011267#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
11268
Guido van Rossum94f6f721999-01-06 18:42:14 +000011269
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011270#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011271/*[clinic input]
11272os._getdiskusage
11273
Steve Dower23ad6d02018-02-22 10:39:10 -080011274 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +100011275
11276Return disk usage statistics about the given path as a (total, free) tuple.
11277[clinic start generated code]*/
11278
Larry Hastings2f936352014-08-05 14:04:04 +100011279static PyObject *
Steve Dower23ad6d02018-02-22 10:39:10 -080011280os__getdiskusage_impl(PyObject *module, path_t *path)
11281/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011282{
11283 BOOL retval;
11284 ULARGE_INTEGER _, total, free;
Joe Pamerc8c02492018-09-25 10:57:36 -040011285 DWORD err = 0;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011286
11287 Py_BEGIN_ALLOW_THREADS
Steve Dower23ad6d02018-02-22 10:39:10 -080011288 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011289 Py_END_ALLOW_THREADS
Joe Pamerc8c02492018-09-25 10:57:36 -040011290 if (retval == 0) {
11291 if (GetLastError() == ERROR_DIRECTORY) {
11292 wchar_t *dir_path = NULL;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011293
Joe Pamerc8c02492018-09-25 10:57:36 -040011294 dir_path = PyMem_New(wchar_t, path->length + 1);
11295 if (dir_path == NULL) {
11296 return PyErr_NoMemory();
11297 }
11298
11299 wcscpy_s(dir_path, path->length + 1, path->wide);
11300
11301 if (_dirnameW(dir_path) != -1) {
11302 Py_BEGIN_ALLOW_THREADS
11303 retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free);
11304 Py_END_ALLOW_THREADS
11305 }
11306 /* Record the last error in case it's modified by PyMem_Free. */
11307 err = GetLastError();
11308 PyMem_Free(dir_path);
11309 if (retval) {
11310 goto success;
11311 }
11312 }
11313 return PyErr_SetFromWindowsErr(err);
11314 }
11315
11316success:
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011317 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
11318}
Larry Hastings2f936352014-08-05 14:04:04 +100011319#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011320
11321
Fred Drakec9680921999-12-13 16:37:25 +000011322/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
11323 * It maps strings representing configuration variable names to
11324 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +000011325 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +000011326 * rarely-used constants. There are three separate tables that use
11327 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +000011328 *
11329 * This code is always included, even if none of the interfaces that
11330 * need it are included. The #if hackery needed to avoid it would be
11331 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +000011332 */
11333struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011334 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011335 int value;
Fred Drakec9680921999-12-13 16:37:25 +000011336};
11337
Fred Drake12c6e2d1999-12-14 21:25:03 +000011338static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011339conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +000011340 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +000011341{
Christian Heimes217cfd12007-12-02 14:31:20 +000011342 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +030011343 int value = _PyLong_AsInt(arg);
11344 if (value == -1 && PyErr_Occurred())
11345 return 0;
11346 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +000011347 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +000011348 }
Guido van Rossumbce56a62007-05-10 18:04:33 +000011349 else {
Stefan Krah0e803b32010-11-26 16:16:47 +000011350 /* look up the value in the table using a binary search */
11351 size_t lo = 0;
11352 size_t mid;
11353 size_t hi = tablesize;
11354 int cmp;
11355 const char *confname;
11356 if (!PyUnicode_Check(arg)) {
11357 PyErr_SetString(PyExc_TypeError,
11358 "configuration names must be strings or integers");
11359 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 }
Serhiy Storchaka06515832016-11-20 09:13:07 +020011361 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +000011362 if (confname == NULL)
11363 return 0;
11364 while (lo < hi) {
11365 mid = (lo + hi) / 2;
11366 cmp = strcmp(confname, table[mid].name);
11367 if (cmp < 0)
11368 hi = mid;
11369 else if (cmp > 0)
11370 lo = mid + 1;
11371 else {
11372 *valuep = table[mid].value;
11373 return 1;
11374 }
11375 }
11376 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
11377 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 }
Fred Drake12c6e2d1999-12-14 21:25:03 +000011379}
11380
11381
11382#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
11383static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011384#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011386#endif
11387#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011388 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011389#endif
Fred Drakec9680921999-12-13 16:37:25 +000011390#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011392#endif
11393#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +000011395#endif
11396#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +000011397 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +000011398#endif
11399#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +000011400 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +000011401#endif
11402#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011403 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011404#endif
11405#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +000011407#endif
11408#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011409 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +000011410#endif
11411#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011412 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011413#endif
11414#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011415 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +000011416#endif
11417#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011418 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011419#endif
11420#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011421 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +000011422#endif
11423#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011425#endif
11426#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +000011428#endif
11429#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011430 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011431#endif
11432#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011433 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +000011434#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +000011435#ifdef _PC_ACL_ENABLED
11436 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
11437#endif
11438#ifdef _PC_MIN_HOLE_SIZE
11439 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
11440#endif
11441#ifdef _PC_ALLOC_SIZE_MIN
11442 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
11443#endif
11444#ifdef _PC_REC_INCR_XFER_SIZE
11445 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
11446#endif
11447#ifdef _PC_REC_MAX_XFER_SIZE
11448 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
11449#endif
11450#ifdef _PC_REC_MIN_XFER_SIZE
11451 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
11452#endif
11453#ifdef _PC_REC_XFER_ALIGN
11454 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
11455#endif
11456#ifdef _PC_SYMLINK_MAX
11457 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
11458#endif
11459#ifdef _PC_XATTR_ENABLED
11460 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
11461#endif
11462#ifdef _PC_XATTR_EXISTS
11463 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
11464#endif
11465#ifdef _PC_TIMESTAMP_RESOLUTION
11466 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
11467#endif
Fred Drakec9680921999-12-13 16:37:25 +000011468};
11469
Fred Drakec9680921999-12-13 16:37:25 +000011470static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011471conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011472{
11473 return conv_confname(arg, valuep, posix_constants_pathconf,
11474 sizeof(posix_constants_pathconf)
11475 / sizeof(struct constdef));
11476}
11477#endif
11478
Larry Hastings2f936352014-08-05 14:04:04 +100011479
Fred Drakec9680921999-12-13 16:37:25 +000011480#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011481/*[clinic input]
11482os.fpathconf -> long
11483
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011484 fd: fildes
Larry Hastings2f936352014-08-05 14:04:04 +100011485 name: path_confname
11486 /
11487
11488Return the configuration limit name for the file descriptor fd.
11489
11490If there is no limit, return -1.
11491[clinic start generated code]*/
11492
Larry Hastings2f936352014-08-05 14:04:04 +100011493static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011494os_fpathconf_impl(PyObject *module, int fd, int name)
Gregory P. Smith3ccb96c2020-06-20 15:06:48 -070011495/*[clinic end generated code: output=d5b7042425fc3e21 input=5b8d2471cfaae186]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011496{
11497 long limit;
11498
11499 errno = 0;
11500 limit = fpathconf(fd, name);
11501 if (limit == -1 && errno != 0)
11502 posix_error();
11503
11504 return limit;
11505}
11506#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011507
11508
11509#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011510/*[clinic input]
11511os.pathconf -> long
11512 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
11513 name: path_confname
11514
11515Return the configuration limit name for the file or directory path.
11516
11517If there is no limit, return -1.
11518On some platforms, path may also be specified as an open file descriptor.
11519 If this functionality is unavailable, using it raises an exception.
11520[clinic start generated code]*/
11521
Larry Hastings2f936352014-08-05 14:04:04 +100011522static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011523os_pathconf_impl(PyObject *module, path_t *path, int name)
11524/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011525{
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 long limit;
Fred Drakec9680921999-12-13 16:37:25 +000011527
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +020011529#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +100011530 if (path->fd != -1)
11531 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +020011532 else
11533#endif
Larry Hastings2f936352014-08-05 14:04:04 +100011534 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +000011535 if (limit == -1 && errno != 0) {
11536 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +000011537 /* could be a path or name problem */
11538 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +000011539 else
Larry Hastings2f936352014-08-05 14:04:04 +100011540 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +000011541 }
Larry Hastings2f936352014-08-05 14:04:04 +100011542
11543 return limit;
Fred Drakec9680921999-12-13 16:37:25 +000011544}
Larry Hastings2f936352014-08-05 14:04:04 +100011545#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +000011546
11547#ifdef HAVE_CONFSTR
11548static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +000011549#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +000011550 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +000011551#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +000011552#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011553 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011554#endif
11555#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011556 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +000011557#endif
Fred Draked86ed291999-12-15 15:34:33 +000011558#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011559 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011560#endif
11561#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011562 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011563#endif
11564#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011565 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011566#endif
11567#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011568 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011569#endif
Fred Drakec9680921999-12-13 16:37:25 +000011570#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011571 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011572#endif
11573#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011574 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011575#endif
11576#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011577 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011578#endif
11579#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011580 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011581#endif
11582#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011583 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011584#endif
11585#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011586 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011587#endif
11588#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011589 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011590#endif
11591#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011592 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011593#endif
Fred Draked86ed291999-12-15 15:34:33 +000011594#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +000011595 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +000011596#endif
Fred Drakec9680921999-12-13 16:37:25 +000011597#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +000011598 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +000011599#endif
Fred Draked86ed291999-12-15 15:34:33 +000011600#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011601 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +000011602#endif
11603#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011604 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +000011605#endif
11606#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011607 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +000011608#endif
11609#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011610 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +000011611#endif
Fred Drakec9680921999-12-13 16:37:25 +000011612#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011613 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011614#endif
11615#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011616 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011617#endif
11618#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011619 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011620#endif
11621#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011622 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011623#endif
11624#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011625 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011626#endif
11627#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011628 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011629#endif
11630#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011631 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011632#endif
11633#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011634 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011635#endif
11636#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011637 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011638#endif
11639#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011640 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011641#endif
11642#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011643 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011644#endif
11645#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011646 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011647#endif
11648#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011649 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011650#endif
11651#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011652 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011653#endif
11654#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000011655 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000011656#endif
11657#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011658 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000011659#endif
Fred Draked86ed291999-12-15 15:34:33 +000011660#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011661 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011662#endif
11663#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000011664 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000011665#endif
11666#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000011667 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000011668#endif
11669#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011670 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011671#endif
11672#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011673 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011674#endif
11675#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000011676 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000011677#endif
11678#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011679 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000011680#endif
11681#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000011682 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000011683#endif
11684#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011685 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000011686#endif
11687#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000011688 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000011689#endif
11690#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000011691 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000011692#endif
11693#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011694 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000011695#endif
11696#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000011697 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000011698#endif
Fred Drakec9680921999-12-13 16:37:25 +000011699};
11700
11701static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000011702conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000011703{
11704 return conv_confname(arg, valuep, posix_constants_confstr,
11705 sizeof(posix_constants_confstr)
11706 / sizeof(struct constdef));
11707}
11708
Larry Hastings2f936352014-08-05 14:04:04 +100011709
11710/*[clinic input]
11711os.confstr
11712
11713 name: confstr_confname
11714 /
11715
11716Return a string-valued system configuration variable.
11717[clinic start generated code]*/
11718
Larry Hastings2f936352014-08-05 14:04:04 +100011719static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011720os_confstr_impl(PyObject *module, int name)
11721/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000011722{
11723 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000011724 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011725 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000011726
Victor Stinnercb043522010-09-10 23:49:04 +000011727 errno = 0;
11728 len = confstr(name, buffer, sizeof(buffer));
11729 if (len == 0) {
11730 if (errno) {
11731 posix_error();
11732 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000011733 }
11734 else {
Victor Stinnercb043522010-09-10 23:49:04 +000011735 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000011736 }
11737 }
Victor Stinnercb043522010-09-10 23:49:04 +000011738
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020011739 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010011740 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000011741 char *buf = PyMem_Malloc(len);
11742 if (buf == NULL)
11743 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010011744 len2 = confstr(name, buf, len);
11745 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020011746 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000011747 PyMem_Free(buf);
11748 }
11749 else
11750 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000011751 return result;
11752}
Larry Hastings2f936352014-08-05 14:04:04 +100011753#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000011754
11755
11756#ifdef HAVE_SYSCONF
11757static struct constdef posix_constants_sysconf[] = {
11758#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011759 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000011760#endif
11761#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000011762 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000011763#endif
11764#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011765 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011766#endif
11767#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011768 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011769#endif
11770#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011771 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011772#endif
11773#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000011774 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000011775#endif
11776#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000011777 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000011778#endif
11779#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000011780 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000011781#endif
11782#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011783 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000011784#endif
11785#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000011786 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000011787#endif
Fred Draked86ed291999-12-15 15:34:33 +000011788#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011789 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000011790#endif
11791#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000011792 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000011793#endif
Fred Drakec9680921999-12-13 16:37:25 +000011794#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011795 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011796#endif
Fred Drakec9680921999-12-13 16:37:25 +000011797#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011798 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011799#endif
11800#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011801 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011802#endif
11803#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011804 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011805#endif
11806#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000011807 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000011808#endif
11809#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011810 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011811#endif
Fred Draked86ed291999-12-15 15:34:33 +000011812#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011813 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000011814#endif
Fred Drakec9680921999-12-13 16:37:25 +000011815#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000011816 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000011817#endif
11818#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011819 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011820#endif
11821#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011822 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011823#endif
11824#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011825 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011826#endif
11827#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011828 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011829#endif
Fred Draked86ed291999-12-15 15:34:33 +000011830#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000011831 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000011832#endif
Fred Drakec9680921999-12-13 16:37:25 +000011833#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011834 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011835#endif
11836#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011837 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011838#endif
11839#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011840 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011841#endif
11842#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011843 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011844#endif
11845#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011846 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011847#endif
11848#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011849 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000011850#endif
11851#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011852 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011853#endif
11854#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011855 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011856#endif
11857#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011858 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011859#endif
11860#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011861 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011862#endif
11863#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011864 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011865#endif
11866#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011867 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011868#endif
11869#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011870 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011871#endif
11872#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011873 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011874#endif
11875#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011876 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011877#endif
11878#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011879 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011880#endif
11881#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011882 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000011883#endif
11884#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011885 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011886#endif
11887#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011888 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011889#endif
11890#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000011891 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000011892#endif
11893#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011894 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000011895#endif
11896#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011897 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000011898#endif
11899#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000011900 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000011901#endif
Fred Draked86ed291999-12-15 15:34:33 +000011902#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000011903 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000011904#endif
Fred Drakec9680921999-12-13 16:37:25 +000011905#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011906 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011907#endif
11908#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011909 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000011910#endif
11911#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011912 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011913#endif
Fred Draked86ed291999-12-15 15:34:33 +000011914#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000011915 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000011916#endif
Fred Drakec9680921999-12-13 16:37:25 +000011917#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000011918 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000011919#endif
Fred Draked86ed291999-12-15 15:34:33 +000011920#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000011921 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000011922#endif
11923#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000011924 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000011925#endif
Fred Drakec9680921999-12-13 16:37:25 +000011926#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011927 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011928#endif
11929#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011930 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011931#endif
11932#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011933 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011934#endif
11935#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011936 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000011937#endif
Fred Draked86ed291999-12-15 15:34:33 +000011938#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000011939 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000011940#endif
Fred Drakec9680921999-12-13 16:37:25 +000011941#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000011942 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000011943#endif
11944#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011945 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000011946#endif
11947#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011948 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011949#endif
11950#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011951 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000011952#endif
11953#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011954 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000011955#endif
11956#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000011957 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000011958#endif
11959#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000011960 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000011961#endif
Fred Draked86ed291999-12-15 15:34:33 +000011962#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000011963 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000011964#endif
Fred Drakec9680921999-12-13 16:37:25 +000011965#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011966 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011967#endif
11968#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011969 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011970#endif
Fred Draked86ed291999-12-15 15:34:33 +000011971#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011972 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000011973#endif
Fred Drakec9680921999-12-13 16:37:25 +000011974#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011975 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000011976#endif
11977#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011978 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011979#endif
11980#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011981 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011982#endif
11983#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011984 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011985#endif
11986#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011987 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011988#endif
11989#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011990 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011991#endif
11992#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011993 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000011994#endif
11995#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011996 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000011997#endif
11998#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000011999 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000012000#endif
Fred Draked86ed291999-12-15 15:34:33 +000012001#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000012002 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000012003#endif
12004#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000012005 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000012006#endif
Fred Drakec9680921999-12-13 16:37:25 +000012007#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000012008 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000012009#endif
12010#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012011 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012012#endif
12013#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012014 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012015#endif
12016#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012017 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012018#endif
Batuhan Taşkaya909f4a32020-04-05 03:40:49 +030012019#ifdef _SC_AIX_REALMEM
12020 {"SC_AIX_REALMEM", _SC_AIX_REALMEM},
12021#endif
Fred Drakec9680921999-12-13 16:37:25 +000012022#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012023 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012024#endif
12025#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000012026 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000012027#endif
12028#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000012029 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000012030#endif
12031#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000012032 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000012033#endif
12034#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012035 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000012036#endif
12037#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000012038 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000012039#endif
12040#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000012041 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000012042#endif
12043#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012044 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000012045#endif
12046#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012047 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000012048#endif
12049#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000012050 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000012051#endif
12052#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000012053 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000012054#endif
12055#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000012056 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000012057#endif
12058#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000012059 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000012060#endif
12061#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012062 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012063#endif
12064#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012065 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012066#endif
12067#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000012068 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000012069#endif
12070#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012071 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012072#endif
12073#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012074 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012075#endif
12076#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000012077 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000012078#endif
12079#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012080 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012081#endif
12082#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012083 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012084#endif
12085#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012086 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000012087#endif
12088#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000012089 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000012090#endif
12091#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012092 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012093#endif
12094#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012095 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012096#endif
12097#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000012098 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000012099#endif
12100#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012101 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012102#endif
12103#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012104 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012105#endif
12106#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012107 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012108#endif
12109#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012110 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012111#endif
12112#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012113 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012114#endif
Fred Draked86ed291999-12-15 15:34:33 +000012115#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000012116 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000012117#endif
Fred Drakec9680921999-12-13 16:37:25 +000012118#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000012119 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000012120#endif
12121#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012122 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012123#endif
12124#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000012125 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000012126#endif
12127#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012128 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012129#endif
12130#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000012131 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000012132#endif
12133#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012134 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012135#endif
12136#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000012137 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000012138#endif
12139#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000012140 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000012141#endif
12142#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012143 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012144#endif
12145#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012146 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012147#endif
12148#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000012149 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000012150#endif
12151#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012152 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000012153#endif
12154#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012155 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000012156#endif
12157#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000012158 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000012159#endif
12160#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000012161 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000012162#endif
12163#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000012164 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000012165#endif
12166#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012167 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012168#endif
12169#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000012170 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000012171#endif
12172#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012173 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012174#endif
12175#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012176 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012177#endif
12178#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012179 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012180#endif
12181#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012182 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012183#endif
12184#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012185 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012186#endif
12187#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012188 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012189#endif
12190#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000012191 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000012192#endif
12193#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012194 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012195#endif
12196#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000012197 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000012198#endif
12199#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012200 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012201#endif
12202#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012203 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000012204#endif
12205#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000012206 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000012207#endif
12208#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012209 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012210#endif
12211#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000012212 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000012213#endif
12214#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000012215 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000012216#endif
12217#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000012218 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000012219#endif
12220#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000012221 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000012222#endif
12223#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000012224 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000012225#endif
12226#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012227 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000012228#endif
12229#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000012230 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000012231#endif
12232#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000012233 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000012234#endif
12235#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000012236 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000012237#endif
12238#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012239 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012240#endif
12241#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000012242 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000012243#endif
12244#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000012245 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000012246#endif
12247#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000012248 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000012249#endif
12250#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000012251 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000012252#endif
12253};
12254
12255static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012256conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000012257{
12258 return conv_confname(arg, valuep, posix_constants_sysconf,
12259 sizeof(posix_constants_sysconf)
12260 / sizeof(struct constdef));
12261}
12262
Larry Hastings2f936352014-08-05 14:04:04 +100012263
12264/*[clinic input]
12265os.sysconf -> long
12266 name: sysconf_confname
12267 /
12268
12269Return an integer-valued system configuration variable.
12270[clinic start generated code]*/
12271
Larry Hastings2f936352014-08-05 14:04:04 +100012272static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012273os_sysconf_impl(PyObject *module, int name)
12274/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012275{
12276 long value;
12277
12278 errno = 0;
12279 value = sysconf(name);
12280 if (value == -1 && errno != 0)
12281 posix_error();
12282 return value;
12283}
12284#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000012285
12286
Fred Drakebec628d1999-12-15 18:31:10 +000012287/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020012288 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000012289 * the exported dictionaries that are used to publish information about the
12290 * names available on the host platform.
12291 *
12292 * Sorting the table at runtime ensures that the table is properly ordered
12293 * when used, even for platforms we're not able to test on. It also makes
12294 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000012295 */
Fred Drakebec628d1999-12-15 18:31:10 +000012296
12297static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012298cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000012299{
12300 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012301 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000012302 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000012303 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000012304
12305 return strcmp(c1->name, c2->name);
12306}
12307
12308static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000012309setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012310 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012311{
Fred Drakebec628d1999-12-15 18:31:10 +000012312 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000012313 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000012314
12315 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
12316 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000012317 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000012318 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012319
Barry Warsaw3155db32000-04-13 15:20:40 +000012320 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000012321 PyObject *o = PyLong_FromLong(table[i].value);
12322 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
12323 Py_XDECREF(o);
12324 Py_DECREF(d);
12325 return -1;
12326 }
12327 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000012328 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000012329 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000012330}
12331
Fred Drakebec628d1999-12-15 18:31:10 +000012332/* Return -1 on failure, 0 on success. */
12333static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000012334setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000012335{
12336#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000012337 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000012338 sizeof(posix_constants_pathconf)
12339 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012340 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012341 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012342#endif
12343#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000012344 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000012345 sizeof(posix_constants_confstr)
12346 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012347 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012348 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012349#endif
12350#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000012351 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000012352 sizeof(posix_constants_sysconf)
12353 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000012354 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000012355 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000012356#endif
Fred Drakebec628d1999-12-15 18:31:10 +000012357 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000012358}
Fred Draked86ed291999-12-15 15:34:33 +000012359
12360
Larry Hastings2f936352014-08-05 14:04:04 +100012361/*[clinic input]
12362os.abort
12363
12364Abort the interpreter immediately.
12365
12366This function 'dumps core' or otherwise fails in the hardest way possible
12367on the hosting operating system. This function never returns.
12368[clinic start generated code]*/
12369
Larry Hastings2f936352014-08-05 14:04:04 +100012370static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012371os_abort_impl(PyObject *module)
12372/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012373{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012374 abort();
12375 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010012376#ifndef __clang__
12377 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
12378 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
12379 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012380 Py_FatalError("abort() called from Python code didn't abort!");
12381 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010012382#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012383}
Fred Drakebec628d1999-12-15 18:31:10 +000012384
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000012385#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012386/* Grab ShellExecute dynamically from shell32 */
12387static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012388static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
12389 LPCWSTR, INT);
12390static int
12391check_ShellExecute()
12392{
12393 HINSTANCE hShell32;
12394
12395 /* only recheck */
12396 if (-1 == has_ShellExecute) {
12397 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070012398 /* Security note: this call is not vulnerable to "DLL hijacking".
12399 SHELL32 is part of "KnownDLLs" and so Windows always load
12400 the system SHELL32.DLL, even if there is another SHELL32.DLL
12401 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080012402 hShell32 = LoadLibraryW(L"SHELL32");
Steve Dower7d0e0c92015-01-24 08:18:24 -080012403 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080012404 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
12405 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070012406 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012407 } else {
12408 has_ShellExecute = 0;
12409 }
Tony Roberts4860f012019-02-02 18:16:42 +010012410 Py_END_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080012411 }
12412 return has_ShellExecute;
12413}
12414
12415
Steve Dowercc16be82016-09-08 10:35:16 -070012416/*[clinic input]
12417os.startfile
12418 filepath: path_t
12419 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000012420
Steve Dowercc16be82016-09-08 10:35:16 -070012421Start a file with its associated application.
12422
12423When "operation" is not specified or "open", this acts like
12424double-clicking the file in Explorer, or giving the file name as an
12425argument to the DOS "start" command: the file is opened with whatever
12426application (if any) its extension is associated.
12427When another "operation" is given, it specifies what should be done with
12428the file. A typical operation is "print".
12429
12430startfile returns as soon as the associated application is launched.
12431There is no option to wait for the application to close, and no way
12432to retrieve the application's exit status.
12433
12434The filepath is relative to the current directory. If you want to use
12435an absolute path, make sure the first character is not a slash ("/");
12436the underlying Win32 ShellExecute function doesn't work if it is.
12437[clinic start generated code]*/
12438
12439static PyObject *
Serhiy Storchakaafb3e712018-12-14 11:19:51 +020012440os_startfile_impl(PyObject *module, path_t *filepath,
12441 const Py_UNICODE *operation)
Serhiy Storchaka279f4462019-09-14 12:24:05 +030012442/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/
Steve Dowercc16be82016-09-08 10:35:16 -070012443{
12444 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080012445
12446 if(!check_ShellExecute()) {
12447 /* If the OS doesn't have ShellExecute, return a
12448 NotImplementedError. */
12449 return PyErr_Format(PyExc_NotImplementedError,
12450 "startfile not available on this platform");
12451 }
12452
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012453 if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) {
Saiyang Gou95f60012020-02-04 16:15:00 -080012454 return NULL;
12455 }
12456
Victor Stinner8c62be82010-05-06 00:08:46 +000012457 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070012458 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080012459 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000012460 Py_END_ALLOW_THREADS
12461
Victor Stinner8c62be82010-05-06 00:08:46 +000012462 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070012463 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020012464 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012465 }
Steve Dowercc16be82016-09-08 10:35:16 -070012466 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000012467}
Larry Hastings2f936352014-08-05 14:04:04 +100012468#endif /* MS_WINDOWS */
12469
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012470
Martin v. Löwis438b5342002-12-27 10:16:42 +000012471#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100012472/*[clinic input]
12473os.getloadavg
12474
12475Return average recent system load information.
12476
12477Return the number of processes in the system run queue averaged over
12478the last 1, 5, and 15 minutes as a tuple of three floats.
12479Raises OSError if the load average was unobtainable.
12480[clinic start generated code]*/
12481
Larry Hastings2f936352014-08-05 14:04:04 +100012482static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012483os_getloadavg_impl(PyObject *module)
12484/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000012485{
12486 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000012487 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000012488 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
12489 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000012490 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000012491 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000012492}
Larry Hastings2f936352014-08-05 14:04:04 +100012493#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000012494
Larry Hastings2f936352014-08-05 14:04:04 +100012495
12496/*[clinic input]
12497os.device_encoding
12498 fd: int
12499
12500Return a string describing the encoding of a terminal's file descriptor.
12501
12502The file descriptor must be attached to a terminal.
12503If the device is not a terminal, return None.
12504[clinic start generated code]*/
12505
Larry Hastings2f936352014-08-05 14:04:04 +100012506static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012507os_device_encoding_impl(PyObject *module, int fd)
12508/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012509{
Brett Cannonefb00c02012-02-29 18:31:31 -050012510 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000012511}
12512
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012513
Larry Hastings2f936352014-08-05 14:04:04 +100012514#ifdef HAVE_SETRESUID
12515/*[clinic input]
12516os.setresuid
12517
12518 ruid: uid_t
12519 euid: uid_t
12520 suid: uid_t
12521 /
12522
12523Set the current process's real, effective, and saved user ids.
12524[clinic start generated code]*/
12525
Larry Hastings2f936352014-08-05 14:04:04 +100012526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012527os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
12528/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012529{
Victor Stinner8c62be82010-05-06 00:08:46 +000012530 if (setresuid(ruid, euid, suid) < 0)
12531 return posix_error();
12532 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012533}
Larry Hastings2f936352014-08-05 14:04:04 +100012534#endif /* HAVE_SETRESUID */
12535
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012536
12537#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012538/*[clinic input]
12539os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012540
Larry Hastings2f936352014-08-05 14:04:04 +100012541 rgid: gid_t
12542 egid: gid_t
12543 sgid: gid_t
12544 /
12545
12546Set the current process's real, effective, and saved group ids.
12547[clinic start generated code]*/
12548
Larry Hastings2f936352014-08-05 14:04:04 +100012549static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012550os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
12551/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012552{
Victor Stinner8c62be82010-05-06 00:08:46 +000012553 if (setresgid(rgid, egid, sgid) < 0)
12554 return posix_error();
12555 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012556}
Larry Hastings2f936352014-08-05 14:04:04 +100012557#endif /* HAVE_SETRESGID */
12558
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012559
12560#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100012561/*[clinic input]
12562os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012563
Larry Hastings2f936352014-08-05 14:04:04 +100012564Return a tuple of the current process's real, effective, and saved user ids.
12565[clinic start generated code]*/
12566
Larry Hastings2f936352014-08-05 14:04:04 +100012567static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012568os_getresuid_impl(PyObject *module)
12569/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012570{
Victor Stinner8c62be82010-05-06 00:08:46 +000012571 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012572 if (getresuid(&ruid, &euid, &suid) < 0)
12573 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012574 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
12575 _PyLong_FromUid(euid),
12576 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012577}
Larry Hastings2f936352014-08-05 14:04:04 +100012578#endif /* HAVE_GETRESUID */
12579
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012580
12581#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100012582/*[clinic input]
12583os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012584
Larry Hastings2f936352014-08-05 14:04:04 +100012585Return a tuple of the current process's real, effective, and saved group ids.
12586[clinic start generated code]*/
12587
Larry Hastings2f936352014-08-05 14:04:04 +100012588static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012589os_getresgid_impl(PyObject *module)
12590/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012591{
12592 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000012593 if (getresgid(&rgid, &egid, &sgid) < 0)
12594 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020012595 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
12596 _PyLong_FromGid(egid),
12597 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012598}
Larry Hastings2f936352014-08-05 14:04:04 +100012599#endif /* HAVE_GETRESGID */
12600
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012601
Benjamin Peterson9428d532011-09-14 11:45:52 -040012602#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100012603/*[clinic input]
12604os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040012605
Larry Hastings2f936352014-08-05 14:04:04 +100012606 path: path_t(allow_fd=True)
12607 attribute: path_t
12608 *
12609 follow_symlinks: bool = True
12610
12611Return the value of extended attribute attribute on path.
12612
BNMetricsb9427072018-11-02 15:20:19 +000012613path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012614If follow_symlinks is False, and the last element of the path is a symbolic
12615 link, getxattr will examine the symbolic link itself instead of the file
12616 the link points to.
12617
12618[clinic start generated code]*/
12619
Larry Hastings2f936352014-08-05 14:04:04 +100012620static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012621os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012622 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012623/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012624{
12625 Py_ssize_t i;
12626 PyObject *buffer = NULL;
12627
12628 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
12629 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012630
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012631 if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
12632 return NULL;
12633 }
12634
Larry Hastings9cf065c2012-06-22 16:30:09 -070012635 for (i = 0; ; i++) {
12636 void *ptr;
12637 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012638 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070012639 Py_ssize_t buffer_size = buffer_sizes[i];
12640 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100012641 path_error(path);
12642 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012643 }
12644 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
12645 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100012646 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012647 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012648
Larry Hastings9cf065c2012-06-22 16:30:09 -070012649 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012650 if (path->fd >= 0)
12651 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012652 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012653 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012654 else
Larry Hastings2f936352014-08-05 14:04:04 +100012655 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012656 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012657
Larry Hastings9cf065c2012-06-22 16:30:09 -070012658 if (result < 0) {
12659 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012660 if (errno == ERANGE)
12661 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100012662 path_error(path);
12663 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012664 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012665
Larry Hastings9cf065c2012-06-22 16:30:09 -070012666 if (result != buffer_size) {
12667 /* Can only shrink. */
12668 _PyBytes_Resize(&buffer, result);
12669 }
12670 break;
12671 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012672
Larry Hastings9cf065c2012-06-22 16:30:09 -070012673 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012674}
12675
Larry Hastings2f936352014-08-05 14:04:04 +100012676
12677/*[clinic input]
12678os.setxattr
12679
12680 path: path_t(allow_fd=True)
12681 attribute: path_t
12682 value: Py_buffer
12683 flags: int = 0
12684 *
12685 follow_symlinks: bool = True
12686
12687Set extended attribute attribute on path to value.
12688
BNMetricsb9427072018-11-02 15:20:19 +000012689path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012690If follow_symlinks is False, and the last element of the path is a symbolic
12691 link, setxattr will modify the symbolic link itself instead of the file
12692 the link points to.
12693
12694[clinic start generated code]*/
12695
Benjamin Peterson799bd802011-08-31 22:15:17 -040012696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012697os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012698 Py_buffer *value, int flags, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012699/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040012700{
Larry Hastings2f936352014-08-05 14:04:04 +100012701 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012702
Larry Hastings2f936352014-08-05 14:04:04 +100012703 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040012704 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012705
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012706 if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object,
12707 value->buf, value->len, flags) < 0) {
12708 return NULL;
12709 }
12710
Benjamin Peterson799bd802011-08-31 22:15:17 -040012711 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012712 if (path->fd > -1)
12713 result = fsetxattr(path->fd, attribute->narrow,
12714 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012715 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100012716 result = setxattr(path->narrow, attribute->narrow,
12717 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012718 else
Larry Hastings2f936352014-08-05 14:04:04 +100012719 result = lsetxattr(path->narrow, attribute->narrow,
12720 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040012721 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012722
Larry Hastings9cf065c2012-06-22 16:30:09 -070012723 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100012724 path_error(path);
12725 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012726 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012727
Larry Hastings2f936352014-08-05 14:04:04 +100012728 Py_RETURN_NONE;
12729}
12730
12731
12732/*[clinic input]
12733os.removexattr
12734
12735 path: path_t(allow_fd=True)
12736 attribute: path_t
12737 *
12738 follow_symlinks: bool = True
12739
12740Remove extended attribute attribute on path.
12741
BNMetricsb9427072018-11-02 15:20:19 +000012742path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012743If follow_symlinks is False, and the last element of the path is a symbolic
12744 link, removexattr will modify the symbolic link itself instead of the file
12745 the link points to.
12746
12747[clinic start generated code]*/
12748
Larry Hastings2f936352014-08-05 14:04:04 +100012749static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012750os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040012751 int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012752/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012753{
12754 ssize_t result;
12755
12756 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
12757 return NULL;
12758
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012759 if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) {
12760 return NULL;
12761 }
12762
Larry Hastings2f936352014-08-05 14:04:04 +100012763 Py_BEGIN_ALLOW_THREADS;
12764 if (path->fd > -1)
12765 result = fremovexattr(path->fd, attribute->narrow);
12766 else if (follow_symlinks)
12767 result = removexattr(path->narrow, attribute->narrow);
12768 else
12769 result = lremovexattr(path->narrow, attribute->narrow);
12770 Py_END_ALLOW_THREADS;
12771
12772 if (result) {
12773 return path_error(path);
12774 }
12775
12776 Py_RETURN_NONE;
12777}
12778
12779
12780/*[clinic input]
12781os.listxattr
12782
12783 path: path_t(allow_fd=True, nullable=True) = None
12784 *
12785 follow_symlinks: bool = True
12786
12787Return a list of extended attributes on path.
12788
BNMetricsb9427072018-11-02 15:20:19 +000012789path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100012790if path is None, listxattr will examine the current directory.
12791If follow_symlinks is False, and the last element of the path is a symbolic
12792 link, listxattr will examine the symbolic link itself instead of the file
12793 the link points to.
12794[clinic start generated code]*/
12795
Larry Hastings2f936352014-08-05 14:04:04 +100012796static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012797os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetricsb9427072018-11-02 15:20:19 +000012798/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012799{
Larry Hastings9cf065c2012-06-22 16:30:09 -070012800 Py_ssize_t i;
12801 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012802 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012803 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012804
Larry Hastings2f936352014-08-05 14:04:04 +100012805 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070012806 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012807
Saiyang Gou7514f4f2020-02-12 23:47:42 -080012808 if (PySys_Audit("os.listxattr", "(O)",
12809 path->object ? path->object : Py_None) < 0) {
12810 return NULL;
12811 }
12812
Larry Hastings2f936352014-08-05 14:04:04 +100012813 name = path->narrow ? path->narrow : ".";
12814
Larry Hastings9cf065c2012-06-22 16:30:09 -070012815 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012816 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012817 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012818 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070012819 Py_ssize_t buffer_size = buffer_sizes[i];
12820 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020012821 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100012822 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012823 break;
12824 }
Victor Stinner00d7abd2020-12-01 09:56:42 +010012825 buffer = PyMem_Malloc(buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012826 if (!buffer) {
12827 PyErr_NoMemory();
12828 break;
12829 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012830
Larry Hastings9cf065c2012-06-22 16:30:09 -070012831 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100012832 if (path->fd > -1)
12833 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012834 else if (follow_symlinks)
12835 length = listxattr(name, buffer, buffer_size);
12836 else
12837 length = llistxattr(name, buffer, buffer_size);
12838 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012839
Larry Hastings9cf065c2012-06-22 16:30:09 -070012840 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020012841 if (errno == ERANGE) {
Victor Stinner00d7abd2020-12-01 09:56:42 +010012842 PyMem_Free(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050012843 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012844 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020012845 }
Larry Hastings2f936352014-08-05 14:04:04 +100012846 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012847 break;
12848 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012849
Larry Hastings9cf065c2012-06-22 16:30:09 -070012850 result = PyList_New(0);
12851 if (!result) {
12852 goto exit;
12853 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040012854
Larry Hastings9cf065c2012-06-22 16:30:09 -070012855 end = buffer + length;
12856 for (trace = start = buffer; trace != end; trace++) {
12857 if (!*trace) {
12858 int error;
12859 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
12860 trace - start);
12861 if (!attribute) {
12862 Py_DECREF(result);
12863 result = NULL;
12864 goto exit;
12865 }
12866 error = PyList_Append(result, attribute);
12867 Py_DECREF(attribute);
12868 if (error) {
12869 Py_DECREF(result);
12870 result = NULL;
12871 goto exit;
12872 }
12873 start = trace + 1;
12874 }
12875 }
12876 break;
12877 }
12878exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070012879 if (buffer)
Victor Stinner00d7abd2020-12-01 09:56:42 +010012880 PyMem_Free(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070012881 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012882}
Benjamin Peterson9428d532011-09-14 11:45:52 -040012883#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040012884
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012885
Larry Hastings2f936352014-08-05 14:04:04 +100012886/*[clinic input]
12887os.urandom
12888
12889 size: Py_ssize_t
12890 /
12891
12892Return a bytes object containing random bytes suitable for cryptographic use.
12893[clinic start generated code]*/
12894
Larry Hastings2f936352014-08-05 14:04:04 +100012895static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030012896os_urandom_impl(PyObject *module, Py_ssize_t size)
12897/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100012898{
12899 PyObject *bytes;
12900 int result;
12901
Georg Brandl2fb477c2012-02-21 00:33:36 +010012902 if (size < 0)
12903 return PyErr_Format(PyExc_ValueError,
12904 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100012905 bytes = PyBytes_FromStringAndSize(NULL, size);
12906 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010012907 return NULL;
12908
Victor Stinnere66987e2016-09-06 16:33:52 -070012909 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100012910 if (result == -1) {
12911 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010012912 return NULL;
12913 }
Larry Hastings2f936352014-08-05 14:04:04 +100012914 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010012915}
12916
Zackery Spytz43fdbd22019-05-29 13:57:07 -060012917#ifdef HAVE_MEMFD_CREATE
12918/*[clinic input]
12919os.memfd_create
12920
12921 name: FSConverter
12922 flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC
12923
12924[clinic start generated code]*/
12925
12926static PyObject *
12927os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags)
12928/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/
12929{
12930 int fd;
12931 const char *bytes = PyBytes_AS_STRING(name);
12932 Py_BEGIN_ALLOW_THREADS
12933 fd = memfd_create(bytes, flags);
12934 Py_END_ALLOW_THREADS
12935 if (fd == -1) {
12936 return PyErr_SetFromErrno(PyExc_OSError);
12937 }
12938 return PyLong_FromLong(fd);
12939}
12940#endif
12941
Christian Heimescd9fed62020-11-13 19:48:52 +010012942#ifdef HAVE_EVENTFD
12943/*[clinic input]
12944os.eventfd
12945
12946 initval: unsigned_int
12947 flags: int(c_default="EFD_CLOEXEC") = EFD_CLOEXEC
12948
12949Creates and returns an event notification file descriptor.
12950[clinic start generated code]*/
12951
12952static PyObject *
12953os_eventfd_impl(PyObject *module, unsigned int initval, int flags)
12954/*[clinic end generated code: output=ce9c9bbd1446f2de input=66203e3c50c4028b]*/
12955
12956{
12957 /* initval is limited to uint32_t, internal counter is uint64_t */
12958 int fd;
12959 Py_BEGIN_ALLOW_THREADS
12960 fd = eventfd(initval, flags);
12961 Py_END_ALLOW_THREADS
12962 if (fd == -1) {
12963 return PyErr_SetFromErrno(PyExc_OSError);
12964 }
12965 return PyLong_FromLong(fd);
12966}
12967
12968/*[clinic input]
12969os.eventfd_read
12970
12971 fd: fildes
12972
12973Read eventfd value
12974[clinic start generated code]*/
12975
12976static PyObject *
12977os_eventfd_read_impl(PyObject *module, int fd)
12978/*[clinic end generated code: output=8f2c7b59a3521fd1 input=110f8b57fa596afe]*/
12979{
12980 eventfd_t value;
12981 int result;
12982 Py_BEGIN_ALLOW_THREADS
12983 result = eventfd_read(fd, &value);
12984 Py_END_ALLOW_THREADS
12985 if (result == -1) {
12986 return PyErr_SetFromErrno(PyExc_OSError);
12987 }
12988 return PyLong_FromUnsignedLongLong(value);
12989}
12990
12991/*[clinic input]
12992os.eventfd_write
12993
12994 fd: fildes
12995 value: unsigned_long_long
12996
12997Write eventfd value.
12998[clinic start generated code]*/
12999
13000static PyObject *
13001os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value)
13002/*[clinic end generated code: output=bebd9040bbf987f5 input=156de8555be5a949]*/
13003{
13004 int result;
13005 Py_BEGIN_ALLOW_THREADS
13006 result = eventfd_write(fd, value);
13007 Py_END_ALLOW_THREADS
13008 if (result == -1) {
13009 return PyErr_SetFromErrno(PyExc_OSError);
13010 }
13011 Py_RETURN_NONE;
13012}
13013#endif /* HAVE_EVENTFD */
13014
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013015/* Terminal size querying */
13016
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013017PyDoc_STRVAR(TerminalSize_docstring,
13018 "A tuple of (columns, lines) for holding terminal window size");
13019
13020static PyStructSequence_Field TerminalSize_fields[] = {
13021 {"columns", "width of the terminal window in characters"},
13022 {"lines", "height of the terminal window in characters"},
13023 {NULL, NULL}
13024};
13025
13026static PyStructSequence_Desc TerminalSize_desc = {
13027 "os.terminal_size",
13028 TerminalSize_docstring,
13029 TerminalSize_fields,
13030 2,
13031};
13032
13033#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013034/*[clinic input]
13035os.get_terminal_size
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013036
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013037 fd: int(c_default="fileno(stdout)", py_default="<unrepresentable>") = -1
13038 /
13039
13040Return the size of the terminal window as (columns, lines).
13041
13042The optional argument fd (default standard output) specifies
13043which file descriptor should be queried.
13044
13045If the file descriptor is not connected to a terminal, an OSError
13046is thrown.
13047
13048This function will only be defined if an implementation is
13049available for this system.
13050
13051shutil.get_terminal_size is the high-level function which should
13052normally be used, os.get_terminal_size is the low-level implementation.
13053[clinic start generated code]*/
13054
13055static PyObject *
13056os_get_terminal_size_impl(PyObject *module, int fd)
13057/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013058{
13059 int columns, lines;
13060 PyObject *termsize;
13061
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013062 /* Under some conditions stdout may not be connected and
13063 * fileno(stdout) may point to an invalid file descriptor. For example
13064 * GUI apps don't have valid standard streams by default.
13065 *
13066 * If this happens, and the optional fd argument is not present,
13067 * the ioctl below will fail returning EBADF. This is what we want.
13068 */
13069
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013070#ifdef TERMSIZE_USE_IOCTL
13071 {
13072 struct winsize w;
13073 if (ioctl(fd, TIOCGWINSZ, &w))
13074 return PyErr_SetFromErrno(PyExc_OSError);
13075 columns = w.ws_col;
13076 lines = w.ws_row;
13077 }
13078#endif /* TERMSIZE_USE_IOCTL */
13079
13080#ifdef TERMSIZE_USE_CONIO
13081 {
13082 DWORD nhandle;
13083 HANDLE handle;
13084 CONSOLE_SCREEN_BUFFER_INFO csbi;
13085 switch (fd) {
13086 case 0: nhandle = STD_INPUT_HANDLE;
13087 break;
13088 case 1: nhandle = STD_OUTPUT_HANDLE;
13089 break;
13090 case 2: nhandle = STD_ERROR_HANDLE;
13091 break;
13092 default:
13093 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
13094 }
13095 handle = GetStdHandle(nhandle);
13096 if (handle == NULL)
13097 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
13098 if (handle == INVALID_HANDLE_VALUE)
13099 return PyErr_SetFromWindowsErr(0);
13100
13101 if (!GetConsoleScreenBufferInfo(handle, &csbi))
13102 return PyErr_SetFromWindowsErr(0);
13103
13104 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
13105 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
13106 }
13107#endif /* TERMSIZE_USE_CONIO */
13108
Serhiy Storchaka2b560312020-04-18 19:14:10 +030013109 PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013110 termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013111 if (termsize == NULL)
13112 return NULL;
13113 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
13114 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
13115 if (PyErr_Occurred()) {
13116 Py_DECREF(termsize);
13117 return NULL;
13118 }
13119 return termsize;
13120}
13121#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
13122
Larry Hastings2f936352014-08-05 14:04:04 +100013123
13124/*[clinic input]
13125os.cpu_count
13126
Charles-François Natali80d62e62015-08-13 20:37:08 +010013127Return the number of CPUs in the system; return None if indeterminable.
13128
13129This number is not equivalent to the number of CPUs the current process can
13130use. The number of usable CPUs can be obtained with
13131``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100013132[clinic start generated code]*/
13133
Larry Hastings2f936352014-08-05 14:04:04 +100013134static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013135os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030013136/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013137{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013138 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013139#ifdef MS_WINDOWS
Steve Doweraa929272019-09-11 16:15:39 +010013140 ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013141#elif defined(__hpux)
13142 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
13143#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
13144 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
pxinwr3405e052020-08-07 13:21:52 +080013145#elif defined(__VXWORKS__)
13146 ncpu = _Py_popcount32(vxCpuEnabledGet());
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013147#elif defined(__DragonFly__) || \
13148 defined(__OpenBSD__) || \
13149 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020013150 defined(__NetBSD__) || \
13151 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020013152 int mib[2];
13153 size_t len = sizeof(ncpu);
13154 mib[0] = CTL_HW;
13155 mib[1] = HW_NCPU;
13156 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
13157 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020013158#endif
13159 if (ncpu >= 1)
13160 return PyLong_FromLong(ncpu);
13161 else
13162 Py_RETURN_NONE;
13163}
13164
Victor Stinnerdaf45552013-08-28 00:53:59 +020013165
Larry Hastings2f936352014-08-05 14:04:04 +100013166/*[clinic input]
13167os.get_inheritable -> bool
13168
13169 fd: int
13170 /
13171
13172Get the close-on-exe flag of the specified file descriptor.
13173[clinic start generated code]*/
13174
Larry Hastings2f936352014-08-05 14:04:04 +100013175static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013176os_get_inheritable_impl(PyObject *module, int fd)
13177/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013178{
Steve Dower8fc89802015-04-12 00:26:27 -040013179 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040013180 _Py_BEGIN_SUPPRESS_IPH
13181 return_value = _Py_get_inheritable(fd);
13182 _Py_END_SUPPRESS_IPH
13183 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100013184}
13185
13186
13187/*[clinic input]
13188os.set_inheritable
13189 fd: int
13190 inheritable: int
13191 /
13192
13193Set the inheritable flag of the specified file descriptor.
13194[clinic start generated code]*/
13195
Larry Hastings2f936352014-08-05 14:04:04 +100013196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030013197os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
13198/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020013199{
Steve Dower8fc89802015-04-12 00:26:27 -040013200 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013201
Steve Dower8fc89802015-04-12 00:26:27 -040013202 _Py_BEGIN_SUPPRESS_IPH
13203 result = _Py_set_inheritable(fd, inheritable, NULL);
13204 _Py_END_SUPPRESS_IPH
13205 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020013206 return NULL;
13207 Py_RETURN_NONE;
13208}
13209
13210
13211#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100013212/*[clinic input]
13213os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070013214 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013215 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020013216
Larry Hastings2f936352014-08-05 14:04:04 +100013217Get the close-on-exe flag of the specified file descriptor.
13218[clinic start generated code]*/
13219
Larry Hastings2f936352014-08-05 14:04:04 +100013220static int
Benjamin Petersonca470632016-09-06 13:47:26 -070013221os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070013222/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013223{
13224 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013225
13226 if (!GetHandleInformation((HANDLE)handle, &flags)) {
13227 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100013228 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013229 }
13230
Larry Hastings2f936352014-08-05 14:04:04 +100013231 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013232}
13233
Victor Stinnerdaf45552013-08-28 00:53:59 +020013234
Larry Hastings2f936352014-08-05 14:04:04 +100013235/*[clinic input]
13236os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070013237 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100013238 inheritable: bool
13239 /
13240
13241Set the inheritable flag of the specified handle.
13242[clinic start generated code]*/
13243
Larry Hastings2f936352014-08-05 14:04:04 +100013244static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070013245os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040013246 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070013247/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100013248{
13249 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020013250 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
13251 PyErr_SetFromWindowsErr(0);
13252 return NULL;
13253 }
13254 Py_RETURN_NONE;
13255}
Larry Hastings2f936352014-08-05 14:04:04 +100013256#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013257
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013258#ifndef MS_WINDOWS
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013259/*[clinic input]
13260os.get_blocking -> bool
13261 fd: int
13262 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013263
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013264Get the blocking mode of the file descriptor.
13265
13266Return False if the O_NONBLOCK flag is set, True if the flag is cleared.
13267[clinic start generated code]*/
13268
13269static int
13270os_get_blocking_impl(PyObject *module, int fd)
13271/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013272{
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013273 int blocking;
13274
Steve Dower8fc89802015-04-12 00:26:27 -040013275 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013276 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040013277 _Py_END_SUPPRESS_IPH
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013278 return blocking;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013279}
13280
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013281/*[clinic input]
13282os.set_blocking
13283 fd: int
13284 blocking: bool(accept={int})
13285 /
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013286
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013287Set the blocking mode of the specified file descriptor.
13288
13289Set the O_NONBLOCK flag if blocking is False,
13290clear the O_NONBLOCK flag otherwise.
13291[clinic start generated code]*/
13292
13293static PyObject *
13294os_set_blocking_impl(PyObject *module, int fd, int blocking)
13295/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013296{
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030013297 int result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013298
Steve Dower8fc89802015-04-12 00:26:27 -040013299 _Py_BEGIN_SUPPRESS_IPH
13300 result = _Py_set_blocking(fd, blocking);
13301 _Py_END_SUPPRESS_IPH
13302 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020013303 return NULL;
13304 Py_RETURN_NONE;
13305}
13306#endif /* !MS_WINDOWS */
13307
13308
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013309/*[clinic input]
Eddie Elizondob3966632019-11-05 07:16:14 -080013310class os.DirEntry "DirEntry *" "DirEntryType"
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013311[clinic start generated code]*/
Eddie Elizondob3966632019-11-05 07:16:14 -080013312/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013313
13314typedef struct {
13315 PyObject_HEAD
13316 PyObject *name;
13317 PyObject *path;
13318 PyObject *stat;
13319 PyObject *lstat;
13320#ifdef MS_WINDOWS
13321 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010013322 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010013323 int got_file_index;
13324#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010013325#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013326 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013327#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013328 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013329 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010013330#endif
13331} DirEntry;
13332
Eddie Elizondob3966632019-11-05 07:16:14 -080013333static PyObject *
13334_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
13335{
13336 PyErr_Format(PyExc_TypeError,
13337 "cannot create '%.100s' instances", _PyType_Name(type));
13338 return NULL;
13339}
13340
Victor Stinner6036e442015-03-08 01:58:04 +010013341static void
13342DirEntry_dealloc(DirEntry *entry)
13343{
Eddie Elizondob3966632019-11-05 07:16:14 -080013344 PyTypeObject *tp = Py_TYPE(entry);
Victor Stinner6036e442015-03-08 01:58:04 +010013345 Py_XDECREF(entry->name);
13346 Py_XDECREF(entry->path);
13347 Py_XDECREF(entry->stat);
13348 Py_XDECREF(entry->lstat);
Eddie Elizondob3966632019-11-05 07:16:14 -080013349 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
13350 free_func(entry);
13351 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010013352}
13353
13354/* Forward reference */
13355static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013356DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13357 int follow_symlinks, unsigned short mode_bits);
Victor Stinner6036e442015-03-08 01:58:04 +010013358
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013359/*[clinic input]
13360os.DirEntry.is_symlink -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013361 defining_class: defining_class
13362 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013363
13364Return True if the entry is a symbolic link; cached per entry.
13365[clinic start generated code]*/
13366
Victor Stinner6036e442015-03-08 01:58:04 +010013367static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013368os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
13369/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013370{
13371#ifdef MS_WINDOWS
13372 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010013373#elif defined(HAVE_DIRENT_D_TYPE)
13374 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010013375 if (self->d_type != DT_UNKNOWN)
13376 return self->d_type == DT_LNK;
13377 else
Victor Stinner97f33c32020-05-14 18:05:58 +020013378 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010013379#else
13380 /* POSIX without d_type */
Victor Stinner97f33c32020-05-14 18:05:58 +020013381 return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010013382#endif
13383}
13384
13385static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013386DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
Victor Stinner6036e442015-03-08 01:58:04 +010013387{
13388 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013389 STRUCT_STAT st;
13390 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010013391
13392#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013393 if (!PyUnicode_FSDecoder(self->path, &ub))
13394 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013395#if USE_UNICODE_WCHAR_CACHE
13396_Py_COMP_DIAG_PUSH
13397_Py_COMP_DIAG_IGNORE_DEPR_DECLS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013398 const wchar_t *path = PyUnicode_AsUnicode(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013399_Py_COMP_DIAG_POP
13400#else /* USE_UNICODE_WCHAR_CACHE */
13401 wchar_t *path = PyUnicode_AsWideCharString(ub, NULL);
13402 Py_DECREF(ub);
13403#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013404#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013405 if (!PyUnicode_FSConverter(self->path, &ub))
13406 return NULL;
13407 const char *path = PyBytes_AS_STRING(ub);
13408 if (self->dir_fd != DEFAULT_DIR_FD) {
13409#ifdef HAVE_FSTATAT
Ronald Oussoren41761932020-11-08 10:05:27 +010013410 if (HAVE_FSTATAT_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013411 result = fstatat(self->dir_fd, path, &st,
13412 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
Ronald Oussoren41761932020-11-08 10:05:27 +010013413 } else
13414
13415#endif /* HAVE_FSTATAT */
13416 {
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013417 Py_DECREF(ub);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013418 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
13419 return NULL;
Ronald Oussoren41761932020-11-08 10:05:27 +010013420 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013421 }
13422 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013423#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013424 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013425 if (follow_symlinks)
13426 result = STAT(path, &st);
13427 else
13428 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013429 }
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013430#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE
13431 PyMem_Free(path);
13432#else /* USE_UNICODE_WCHAR_CACHE */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013433 Py_DECREF(ub);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013434#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013435
13436 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013437 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013438
Victor Stinner97f33c32020-05-14 18:05:58 +020013439 return _pystat_fromstructstat(module, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010013440}
13441
13442static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013443DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
Victor Stinner6036e442015-03-08 01:58:04 +010013444{
13445 if (!self->lstat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013446 PyObject *module = PyType_GetModule(defining_class);
Victor Stinner6036e442015-03-08 01:58:04 +010013447#ifdef MS_WINDOWS
Victor Stinner97f33c32020-05-14 18:05:58 +020013448 self->lstat = _pystat_fromstructstat(module, &self->win32_lstat);
Victor Stinner6036e442015-03-08 01:58:04 +010013449#else /* POSIX */
Victor Stinner97f33c32020-05-14 18:05:58 +020013450 self->lstat = DirEntry_fetch_stat(module, self, 0);
Victor Stinner6036e442015-03-08 01:58:04 +010013451#endif
13452 }
13453 Py_XINCREF(self->lstat);
13454 return self->lstat;
13455}
13456
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013457/*[clinic input]
13458os.DirEntry.stat
Victor Stinner97f33c32020-05-14 18:05:58 +020013459 defining_class: defining_class
13460 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013461 *
13462 follow_symlinks: bool = True
13463
13464Return stat_result object for the entry; cached per entry.
13465[clinic start generated code]*/
13466
Victor Stinner6036e442015-03-08 01:58:04 +010013467static PyObject *
Victor Stinner97f33c32020-05-14 18:05:58 +020013468os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
13469 int follow_symlinks)
13470/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013471{
Victor Stinner97f33c32020-05-14 18:05:58 +020013472 if (!follow_symlinks) {
13473 return DirEntry_get_lstat(defining_class, self);
13474 }
Victor Stinner6036e442015-03-08 01:58:04 +010013475
13476 if (!self->stat) {
Victor Stinner97f33c32020-05-14 18:05:58 +020013477 int result = os_DirEntry_is_symlink_impl(self, defining_class);
13478 if (result == -1) {
Victor Stinner6036e442015-03-08 01:58:04 +010013479 return NULL;
Victor Stinner97f33c32020-05-14 18:05:58 +020013480 }
13481 if (result) {
13482 PyObject *module = PyType_GetModule(defining_class);
13483 self->stat = DirEntry_fetch_stat(module, self, 1);
13484 }
13485 else {
13486 self->stat = DirEntry_get_lstat(defining_class, self);
13487 }
Victor Stinner6036e442015-03-08 01:58:04 +010013488 }
13489
13490 Py_XINCREF(self->stat);
13491 return self->stat;
13492}
13493
Victor Stinner6036e442015-03-08 01:58:04 +010013494/* Set exception and return -1 on error, 0 for False, 1 for True */
13495static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013496DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
13497 int follow_symlinks, unsigned short mode_bits)
Victor Stinner6036e442015-03-08 01:58:04 +010013498{
13499 PyObject *stat = NULL;
13500 PyObject *st_mode = NULL;
13501 long mode;
13502 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010013503#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013504 int is_symlink;
13505 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010013506#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013507#ifdef MS_WINDOWS
13508 unsigned long dir_bits;
13509#endif
13510
13511#ifdef MS_WINDOWS
13512 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
13513 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010013514#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013515 is_symlink = self->d_type == DT_LNK;
13516 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
13517#endif
13518
Victor Stinner35a97c02015-03-08 02:59:09 +010013519#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013520 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010013521#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020013522 stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010013523 if (!stat) {
13524 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
13525 /* If file doesn't exist (anymore), then return False
13526 (i.e., say it's not a file/directory) */
13527 PyErr_Clear();
13528 return 0;
13529 }
13530 goto error;
13531 }
Victor Stinner97f33c32020-05-14 18:05:58 +020013532 _posixstate* state = get_posix_state(PyType_GetModule(defining_class));
13533 st_mode = PyObject_GetAttr(stat, state->st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010013534 if (!st_mode)
13535 goto error;
13536
13537 mode = PyLong_AsLong(st_mode);
13538 if (mode == -1 && PyErr_Occurred())
13539 goto error;
13540 Py_CLEAR(st_mode);
13541 Py_CLEAR(stat);
13542 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010013543#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010013544 }
13545 else if (is_symlink) {
13546 assert(mode_bits != S_IFLNK);
13547 result = 0;
13548 }
13549 else {
13550 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
13551#ifdef MS_WINDOWS
13552 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
13553 if (mode_bits == S_IFDIR)
13554 result = dir_bits != 0;
13555 else
13556 result = dir_bits == 0;
13557#else /* POSIX */
13558 if (mode_bits == S_IFDIR)
13559 result = self->d_type == DT_DIR;
13560 else
13561 result = self->d_type == DT_REG;
13562#endif
13563 }
Victor Stinner35a97c02015-03-08 02:59:09 +010013564#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013565
13566 return result;
13567
13568error:
13569 Py_XDECREF(st_mode);
13570 Py_XDECREF(stat);
13571 return -1;
13572}
13573
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013574/*[clinic input]
13575os.DirEntry.is_dir -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013576 defining_class: defining_class
13577 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013578 *
13579 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010013580
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013581Return True if the entry is a directory; cached per entry.
13582[clinic start generated code]*/
13583
13584static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013585os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
13586 int follow_symlinks)
13587/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013588{
Victor Stinner97f33c32020-05-14 18:05:58 +020013589 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010013590}
13591
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013592/*[clinic input]
13593os.DirEntry.is_file -> bool
Victor Stinner97f33c32020-05-14 18:05:58 +020013594 defining_class: defining_class
13595 /
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013596 *
13597 follow_symlinks: bool = True
13598
13599Return True if the entry is a file; cached per entry.
13600[clinic start generated code]*/
13601
13602static int
Victor Stinner97f33c32020-05-14 18:05:58 +020013603os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
13604 int follow_symlinks)
13605/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013606{
Victor Stinner97f33c32020-05-14 18:05:58 +020013607 return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010013608}
13609
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013610/*[clinic input]
13611os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010013612
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013613Return inode of the entry; cached per entry.
13614[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013615
13616static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013617os_DirEntry_inode_impl(DirEntry *self)
13618/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010013619{
13620#ifdef MS_WINDOWS
13621 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013622 PyObject *unicode;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013623 STRUCT_STAT stat;
13624 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010013625
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013626 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010013627 return NULL;
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013628#if USE_UNICODE_WCHAR_CACHE
13629_Py_COMP_DIAG_PUSH
13630_Py_COMP_DIAG_IGNORE_DEPR_DECLS
13631 const wchar_t *path = PyUnicode_AsUnicode(unicode);
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013632 result = LSTAT(path, &stat);
13633 Py_DECREF(unicode);
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030013634_Py_COMP_DIAG_POP
13635#else /* USE_UNICODE_WCHAR_CACHE */
13636 wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL);
13637 Py_DECREF(unicode);
13638 result = LSTAT(path, &stat);
13639 PyMem_Free(path);
13640#endif /* USE_UNICODE_WCHAR_CACHE */
Victor Stinner6036e442015-03-08 01:58:04 +010013641
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030013642 if (result != 0)
13643 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013644
13645 self->win32_file_index = stat.st_ino;
13646 self->got_file_index = 1;
13647 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010013648 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
13649 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010013650#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020013651 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
13652 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010013653#endif
13654}
13655
13656static PyObject *
13657DirEntry_repr(DirEntry *self)
13658{
13659 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
13660}
13661
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013662/*[clinic input]
13663os.DirEntry.__fspath__
13664
13665Returns the path for the entry.
13666[clinic start generated code]*/
13667
Brett Cannon96881cd2016-06-10 14:37:21 -070013668static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013669os_DirEntry___fspath___impl(DirEntry *self)
13670/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070013671{
13672 Py_INCREF(self->path);
13673 return self->path;
13674}
13675
Victor Stinner6036e442015-03-08 01:58:04 +010013676static PyMemberDef DirEntry_members[] = {
13677 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
13678 "the entry's base filename, relative to scandir() \"path\" argument"},
13679 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
13680 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
13681 {NULL}
13682};
13683
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013684#include "clinic/posixmodule.c.h"
13685
Victor Stinner6036e442015-03-08 01:58:04 +010013686static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020013687 OS_DIRENTRY_IS_DIR_METHODDEF
13688 OS_DIRENTRY_IS_FILE_METHODDEF
13689 OS_DIRENTRY_IS_SYMLINK_METHODDEF
13690 OS_DIRENTRY_STAT_METHODDEF
13691 OS_DIRENTRY_INODE_METHODDEF
13692 OS_DIRENTRY___FSPATH___METHODDEF
Batuhan Taşkayaf9dd51e2020-04-08 00:37:19 +030013693 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
13694 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Victor Stinner6036e442015-03-08 01:58:04 +010013695 {NULL}
13696};
13697
Eddie Elizondob3966632019-11-05 07:16:14 -080013698static PyType_Slot DirEntryType_slots[] = {
13699 {Py_tp_new, _disabled_new},
13700 {Py_tp_dealloc, DirEntry_dealloc},
13701 {Py_tp_repr, DirEntry_repr},
13702 {Py_tp_methods, DirEntry_methods},
13703 {Py_tp_members, DirEntry_members},
13704 {0, 0},
Victor Stinner6036e442015-03-08 01:58:04 +010013705};
13706
Eddie Elizondob3966632019-11-05 07:16:14 -080013707static PyType_Spec DirEntryType_spec = {
13708 MODNAME ".DirEntry",
13709 sizeof(DirEntry),
13710 0,
13711 Py_TPFLAGS_DEFAULT,
13712 DirEntryType_slots
13713};
13714
13715
Victor Stinner6036e442015-03-08 01:58:04 +010013716#ifdef MS_WINDOWS
13717
13718static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030013719join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010013720{
13721 Py_ssize_t path_len;
13722 Py_ssize_t size;
13723 wchar_t *result;
13724 wchar_t ch;
13725
13726 if (!path_wide) { /* Default arg: "." */
13727 path_wide = L".";
13728 path_len = 1;
13729 }
13730 else {
13731 path_len = wcslen(path_wide);
13732 }
13733
13734 /* The +1's are for the path separator and the NUL */
13735 size = path_len + 1 + wcslen(filename) + 1;
13736 result = PyMem_New(wchar_t, size);
13737 if (!result) {
13738 PyErr_NoMemory();
13739 return NULL;
13740 }
13741 wcscpy(result, path_wide);
13742 if (path_len > 0) {
13743 ch = result[path_len - 1];
13744 if (ch != SEP && ch != ALTSEP && ch != L':')
13745 result[path_len++] = SEP;
13746 wcscpy(result + path_len, filename);
13747 }
13748 return result;
13749}
13750
13751static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013752DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
Victor Stinner6036e442015-03-08 01:58:04 +010013753{
13754 DirEntry *entry;
13755 BY_HANDLE_FILE_INFORMATION file_info;
13756 ULONG reparse_tag;
13757 wchar_t *joined_path;
13758
Victor Stinner1c2fa782020-05-10 11:05:29 +020013759 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013760 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013761 if (!entry)
13762 return NULL;
13763 entry->name = NULL;
13764 entry->path = NULL;
13765 entry->stat = NULL;
13766 entry->lstat = NULL;
13767 entry->got_file_index = 0;
13768
13769 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
13770 if (!entry->name)
13771 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013772 if (path->narrow) {
13773 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
13774 if (!entry->name)
13775 goto error;
13776 }
Victor Stinner6036e442015-03-08 01:58:04 +010013777
13778 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
13779 if (!joined_path)
13780 goto error;
13781
13782 entry->path = PyUnicode_FromWideChar(joined_path, -1);
13783 PyMem_Free(joined_path);
13784 if (!entry->path)
13785 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070013786 if (path->narrow) {
13787 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
13788 if (!entry->path)
13789 goto error;
13790 }
Victor Stinner6036e442015-03-08 01:58:04 +010013791
Steve Dowercc16be82016-09-08 10:35:16 -070013792 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010013793 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
13794
13795 return (PyObject *)entry;
13796
13797error:
13798 Py_DECREF(entry);
13799 return NULL;
13800}
13801
13802#else /* POSIX */
13803
13804static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020013805join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010013806{
13807 Py_ssize_t path_len;
13808 Py_ssize_t size;
13809 char *result;
13810
13811 if (!path_narrow) { /* Default arg: "." */
13812 path_narrow = ".";
13813 path_len = 1;
13814 }
13815 else {
13816 path_len = strlen(path_narrow);
13817 }
13818
13819 if (filename_len == -1)
13820 filename_len = strlen(filename);
13821
13822 /* The +1's are for the path separator and the NUL */
13823 size = path_len + 1 + filename_len + 1;
13824 result = PyMem_New(char, size);
13825 if (!result) {
13826 PyErr_NoMemory();
13827 return NULL;
13828 }
13829 strcpy(result, path_narrow);
13830 if (path_len > 0 && result[path_len - 1] != '/')
13831 result[path_len++] = '/';
13832 strcpy(result + path_len, filename);
13833 return result;
13834}
13835
13836static PyObject *
Victor Stinner1c2fa782020-05-10 11:05:29 +020013837DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
13838 Py_ssize_t name_len, ino_t d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010013839#ifdef HAVE_DIRENT_D_TYPE
13840 , unsigned char d_type
13841#endif
13842 )
Victor Stinner6036e442015-03-08 01:58:04 +010013843{
13844 DirEntry *entry;
13845 char *joined_path;
13846
Victor Stinner1c2fa782020-05-10 11:05:29 +020013847 PyObject *DirEntryType = get_posix_state(module)->DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080013848 entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType);
Victor Stinner6036e442015-03-08 01:58:04 +010013849 if (!entry)
13850 return NULL;
13851 entry->name = NULL;
13852 entry->path = NULL;
13853 entry->stat = NULL;
13854 entry->lstat = NULL;
13855
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013856 if (path->fd != -1) {
13857 entry->dir_fd = path->fd;
13858 joined_path = NULL;
13859 }
13860 else {
13861 entry->dir_fd = DEFAULT_DIR_FD;
13862 joined_path = join_path_filename(path->narrow, name, name_len);
13863 if (!joined_path)
13864 goto error;
13865 }
Victor Stinner6036e442015-03-08 01:58:04 +010013866
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030013867 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010013868 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013869 if (joined_path)
13870 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013871 }
13872 else {
13873 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013874 if (joined_path)
13875 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010013876 }
13877 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013878 if (!entry->name)
13879 goto error;
13880
13881 if (path->fd != -1) {
13882 entry->path = entry->name;
13883 Py_INCREF(entry->path);
13884 }
13885 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010013886 goto error;
13887
Victor Stinner35a97c02015-03-08 02:59:09 +010013888#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010013889 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010013890#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013891 entry->d_ino = d_ino;
13892
13893 return (PyObject *)entry;
13894
13895error:
13896 Py_XDECREF(entry);
13897 return NULL;
13898}
13899
13900#endif
13901
13902
13903typedef struct {
13904 PyObject_HEAD
13905 path_t path;
13906#ifdef MS_WINDOWS
13907 HANDLE handle;
13908 WIN32_FIND_DATAW file_data;
13909 int first_time;
13910#else /* POSIX */
13911 DIR *dirp;
13912#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030013913#ifdef HAVE_FDOPENDIR
13914 int fd;
13915#endif
Victor Stinner6036e442015-03-08 01:58:04 +010013916} ScandirIterator;
13917
13918#ifdef MS_WINDOWS
13919
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013920static int
13921ScandirIterator_is_closed(ScandirIterator *iterator)
13922{
13923 return iterator->handle == INVALID_HANDLE_VALUE;
13924}
13925
Victor Stinner6036e442015-03-08 01:58:04 +010013926static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013927ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013928{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013929 HANDLE handle = iterator->handle;
13930
13931 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013932 return;
13933
Victor Stinner6036e442015-03-08 01:58:04 +010013934 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013935 Py_BEGIN_ALLOW_THREADS
13936 FindClose(handle);
13937 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010013938}
13939
13940static PyObject *
13941ScandirIterator_iternext(ScandirIterator *iterator)
13942{
13943 WIN32_FIND_DATAW *file_data = &iterator->file_data;
13944 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013945 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010013946
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013947 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013948 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010013949 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013950
13951 while (1) {
13952 if (!iterator->first_time) {
13953 Py_BEGIN_ALLOW_THREADS
13954 success = FindNextFileW(iterator->handle, file_data);
13955 Py_END_ALLOW_THREADS
13956 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013957 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010013958 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013959 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010013960 break;
13961 }
13962 }
13963 iterator->first_time = 0;
13964
13965 /* Skip over . and .. */
13966 if (wcscmp(file_data->cFileName, L".") != 0 &&
Victor Stinner1c2fa782020-05-10 11:05:29 +020013967 wcscmp(file_data->cFileName, L"..") != 0)
13968 {
13969 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
13970 entry = DirEntry_from_find_data(module, &iterator->path, file_data);
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013971 if (!entry)
13972 break;
13973 return entry;
13974 }
Victor Stinner6036e442015-03-08 01:58:04 +010013975
13976 /* Loop till we get a non-dot directory or finish iterating */
13977 }
13978
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020013979 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013980 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010013981 return NULL;
13982}
13983
13984#else /* POSIX */
13985
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013986static int
13987ScandirIterator_is_closed(ScandirIterator *iterator)
13988{
13989 return !iterator->dirp;
13990}
13991
Victor Stinner6036e442015-03-08 01:58:04 +010013992static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020013993ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010013994{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030013995 DIR *dirp = iterator->dirp;
13996
13997 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010013998 return;
13999
Victor Stinner6036e442015-03-08 01:58:04 +010014000 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014001 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014002#ifdef HAVE_FDOPENDIR
14003 if (iterator->path.fd != -1)
14004 rewinddir(dirp);
14005#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030014006 closedir(dirp);
14007 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010014008 return;
14009}
14010
14011static PyObject *
14012ScandirIterator_iternext(ScandirIterator *iterator)
14013{
14014 struct dirent *direntp;
14015 Py_ssize_t name_len;
14016 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014017 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014018
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014019 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014020 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010014021 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014022
14023 while (1) {
14024 errno = 0;
14025 Py_BEGIN_ALLOW_THREADS
14026 direntp = readdir(iterator->dirp);
14027 Py_END_ALLOW_THREADS
14028
14029 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014030 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010014031 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014032 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010014033 break;
14034 }
14035
14036 /* Skip over . and .. */
14037 name_len = NAMLEN(direntp);
14038 is_dot = direntp->d_name[0] == '.' &&
14039 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
14040 if (!is_dot) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020014041 PyObject *module = PyType_GetModule(Py_TYPE(iterator));
14042 entry = DirEntry_from_posix_info(module,
14043 &iterator->path, direntp->d_name,
14044 name_len, direntp->d_ino
Victor Stinner35a97c02015-03-08 02:59:09 +010014045#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner1c2fa782020-05-10 11:05:29 +020014046 , direntp->d_type
Victor Stinner35a97c02015-03-08 02:59:09 +010014047#endif
14048 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014049 if (!entry)
14050 break;
14051 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010014052 }
14053
14054 /* Loop till we get a non-dot directory or finish iterating */
14055 }
14056
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020014057 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014058 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010014059 return NULL;
14060}
14061
14062#endif
14063
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014064static PyObject *
14065ScandirIterator_close(ScandirIterator *self, PyObject *args)
14066{
14067 ScandirIterator_closedir(self);
14068 Py_RETURN_NONE;
14069}
14070
14071static PyObject *
14072ScandirIterator_enter(PyObject *self, PyObject *args)
14073{
14074 Py_INCREF(self);
14075 return self;
14076}
14077
14078static PyObject *
14079ScandirIterator_exit(ScandirIterator *self, PyObject *args)
14080{
14081 ScandirIterator_closedir(self);
14082 Py_RETURN_NONE;
14083}
14084
Victor Stinner6036e442015-03-08 01:58:04 +010014085static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010014086ScandirIterator_finalize(ScandirIterator *iterator)
14087{
14088 PyObject *error_type, *error_value, *error_traceback;
14089
14090 /* Save the current exception, if any. */
14091 PyErr_Fetch(&error_type, &error_value, &error_traceback);
14092
14093 if (!ScandirIterator_is_closed(iterator)) {
14094 ScandirIterator_closedir(iterator);
14095
14096 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
14097 "unclosed scandir iterator %R", iterator)) {
14098 /* Spurious errors can appear at shutdown */
14099 if (PyErr_ExceptionMatches(PyExc_Warning)) {
14100 PyErr_WriteUnraisable((PyObject *) iterator);
14101 }
14102 }
14103 }
14104
Victor Stinner7bfa4092016-03-23 00:43:54 +010014105 path_cleanup(&iterator->path);
14106
14107 /* Restore the saved exception. */
14108 PyErr_Restore(error_type, error_value, error_traceback);
14109}
14110
14111static void
Victor Stinner6036e442015-03-08 01:58:04 +010014112ScandirIterator_dealloc(ScandirIterator *iterator)
14113{
Eddie Elizondob3966632019-11-05 07:16:14 -080014114 PyTypeObject *tp = Py_TYPE(iterator);
Victor Stinner7bfa4092016-03-23 00:43:54 +010014115 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
14116 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014117
Eddie Elizondob3966632019-11-05 07:16:14 -080014118 freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
14119 free_func(iterator);
14120 Py_DECREF(tp);
Victor Stinner6036e442015-03-08 01:58:04 +010014121}
14122
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020014123static PyMethodDef ScandirIterator_methods[] = {
14124 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
14125 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
14126 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
14127 {NULL}
14128};
14129
Eddie Elizondob3966632019-11-05 07:16:14 -080014130static PyType_Slot ScandirIteratorType_slots[] = {
14131 {Py_tp_new, _disabled_new},
14132 {Py_tp_dealloc, ScandirIterator_dealloc},
14133 {Py_tp_finalize, ScandirIterator_finalize},
14134 {Py_tp_iter, PyObject_SelfIter},
14135 {Py_tp_iternext, ScandirIterator_iternext},
14136 {Py_tp_methods, ScandirIterator_methods},
14137 {0, 0},
14138};
14139
14140static PyType_Spec ScandirIteratorType_spec = {
14141 MODNAME ".ScandirIterator",
14142 sizeof(ScandirIterator),
14143 0,
Victor Stinner97f33c32020-05-14 18:05:58 +020014144 // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
14145 // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
Eddie Elizondob3966632019-11-05 07:16:14 -080014146 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
14147 ScandirIteratorType_slots
Victor Stinner6036e442015-03-08 01:58:04 +010014148};
14149
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014150/*[clinic input]
14151os.scandir
14152
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014153 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014154
14155Return an iterator of DirEntry objects for given path.
14156
BNMetricsb9427072018-11-02 15:20:19 +000014157path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014158is bytes, the names of yielded DirEntry objects will also be bytes; in
14159all other circumstances they will be str.
14160
14161If path is None, uses the path='.'.
14162[clinic start generated code]*/
14163
Victor Stinner6036e442015-03-08 01:58:04 +010014164static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014165os_scandir_impl(PyObject *module, path_t *path)
BNMetricsb9427072018-11-02 15:20:19 +000014166/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010014167{
14168 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010014169#ifdef MS_WINDOWS
14170 wchar_t *path_strW;
14171#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014172 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014173#ifdef HAVE_FDOPENDIR
14174 int fd = -1;
14175#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014176#endif
14177
Steve Dower60419a72019-06-24 08:42:54 -070014178 if (PySys_Audit("os.scandir", "O",
14179 path->object ? path->object : Py_None) < 0) {
14180 return NULL;
14181 }
14182
Hai Shif707d942020-03-16 21:15:01 +080014183 PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080014184 iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType);
Victor Stinner6036e442015-03-08 01:58:04 +010014185 if (!iterator)
14186 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010014187
14188#ifdef MS_WINDOWS
14189 iterator->handle = INVALID_HANDLE_VALUE;
14190#else
14191 iterator->dirp = NULL;
14192#endif
14193
Serhiy Storchaka095ef732017-02-09 20:05:51 +020014194 /* Move the ownership to iterator->path */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014195 memcpy(&iterator->path, path, sizeof(path_t));
14196 memset(path, 0, sizeof(path_t));
Victor Stinner6036e442015-03-08 01:58:04 +010014197
14198#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010014199 iterator->first_time = 1;
14200
14201 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
14202 if (!path_strW)
14203 goto error;
14204
14205 Py_BEGIN_ALLOW_THREADS
14206 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
14207 Py_END_ALLOW_THREADS
14208
14209 PyMem_Free(path_strW);
14210
14211 if (iterator->handle == INVALID_HANDLE_VALUE) {
14212 path_error(&iterator->path);
14213 goto error;
14214 }
14215#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010014216 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014217#ifdef HAVE_FDOPENDIR
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014218 if (iterator->path.fd != -1) {
Ronald Oussoren41761932020-11-08 10:05:27 +010014219 if (HAVE_FDOPENDIR_RUNTIME) {
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014220 /* closedir() closes the FD, so we duplicate it */
Serhiy Storchaka4c8f09d2020-07-10 23:26:06 +030014221 fd = _Py_dup(iterator->path.fd);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014222 if (fd == -1)
14223 goto error;
14224
14225 Py_BEGIN_ALLOW_THREADS
14226 iterator->dirp = fdopendir(fd);
14227 Py_END_ALLOW_THREADS
Ronald Oussoren41761932020-11-08 10:05:27 +010014228 } else {
14229 PyErr_SetString(PyExc_TypeError,
14230 "scandir: path should be string, bytes, os.PathLike or None, not int");
14231 return NULL;
14232 }
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014233 }
14234 else
14235#endif
14236 {
14237 if (iterator->path.narrow)
14238 path_str = iterator->path.narrow;
14239 else
14240 path_str = ".";
14241
14242 Py_BEGIN_ALLOW_THREADS
14243 iterator->dirp = opendir(path_str);
14244 Py_END_ALLOW_THREADS
14245 }
Victor Stinner6036e442015-03-08 01:58:04 +010014246
14247 if (!iterator->dirp) {
14248 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030014249#ifdef HAVE_FDOPENDIR
14250 if (fd != -1) {
14251 Py_BEGIN_ALLOW_THREADS
14252 close(fd);
14253 Py_END_ALLOW_THREADS
14254 }
14255#endif
Victor Stinner6036e442015-03-08 01:58:04 +010014256 goto error;
14257 }
14258#endif
14259
14260 return (PyObject *)iterator;
14261
14262error:
14263 Py_DECREF(iterator);
14264 return NULL;
14265}
14266
Ethan Furman410ef8e2016-06-04 12:06:26 -070014267/*
14268 Return the file system path representation of the object.
14269
14270 If the object is str or bytes, then allow it to pass through with
14271 an incremented refcount. If the object defines __fspath__(), then
14272 return the result of that method. All other types raise a TypeError.
14273*/
14274PyObject *
14275PyOS_FSPath(PyObject *path)
14276{
Brett Cannon3f9183b2016-08-26 14:44:48 -070014277 /* For error message reasons, this function is manually inlined in
14278 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070014279 PyObject *func = NULL;
14280 PyObject *path_repr = NULL;
14281
14282 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
14283 Py_INCREF(path);
14284 return path;
14285 }
14286
14287 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
14288 if (NULL == func) {
14289 return PyErr_Format(PyExc_TypeError,
14290 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014291 "not %.200s",
Eddie Elizondob3966632019-11-05 07:16:14 -080014292 _PyType_Name(Py_TYPE(path)));
Ethan Furman410ef8e2016-06-04 12:06:26 -070014293 }
14294
Victor Stinnerf17c3de2016-12-06 18:46:19 +010014295 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070014296 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070014297 if (NULL == path_repr) {
14298 return NULL;
14299 }
14300
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014301 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
14302 PyErr_Format(PyExc_TypeError,
14303 "expected %.200s.__fspath__() to return str or bytes, "
Eddie Elizondob3966632019-11-05 07:16:14 -080014304 "not %.200s", _PyType_Name(Py_TYPE(path)),
14305 _PyType_Name(Py_TYPE(path_repr)));
Brett Cannonc78ca1e2016-06-24 12:03:43 -070014306 Py_DECREF(path_repr);
14307 return NULL;
14308 }
14309
Ethan Furman410ef8e2016-06-04 12:06:26 -070014310 return path_repr;
14311}
14312
14313/*[clinic input]
14314os.fspath
14315
14316 path: object
14317
14318Return the file system path representation of the object.
14319
Brett Cannonb4f43e92016-06-09 14:32:08 -070014320If the object is str or bytes, then allow it to pass through as-is. If the
14321object defines __fspath__(), then return the result of that method. All other
14322types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070014323[clinic start generated code]*/
14324
14325static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030014326os_fspath_impl(PyObject *module, PyObject *path)
14327/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070014328{
14329 return PyOS_FSPath(path);
14330}
Victor Stinner6036e442015-03-08 01:58:04 +010014331
Victor Stinner9b1f4742016-09-06 16:18:52 -070014332#ifdef HAVE_GETRANDOM_SYSCALL
14333/*[clinic input]
14334os.getrandom
14335
14336 size: Py_ssize_t
14337 flags: int=0
14338
14339Obtain a series of random bytes.
14340[clinic start generated code]*/
14341
14342static PyObject *
14343os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
14344/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
14345{
Victor Stinner9b1f4742016-09-06 16:18:52 -070014346 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014347 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014348
14349 if (size < 0) {
14350 errno = EINVAL;
14351 return posix_error();
14352 }
14353
Victor Stinnerec2319c2016-09-20 23:00:59 +020014354 bytes = PyBytes_FromStringAndSize(NULL, size);
14355 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014356 PyErr_NoMemory();
14357 return NULL;
14358 }
14359
14360 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014361 n = syscall(SYS_getrandom,
14362 PyBytes_AS_STRING(bytes),
14363 PyBytes_GET_SIZE(bytes),
14364 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070014365 if (n < 0 && errno == EINTR) {
14366 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020014367 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014368 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020014369
14370 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070014371 continue;
14372 }
14373 break;
14374 }
14375
14376 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070014377 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020014378 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014379 }
14380
Victor Stinnerec2319c2016-09-20 23:00:59 +020014381 if (n != size) {
14382 _PyBytes_Resize(&bytes, n);
14383 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070014384
14385 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020014386
14387error:
14388 Py_DECREF(bytes);
14389 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070014390}
14391#endif /* HAVE_GETRANDOM_SYSCALL */
14392
Steve Dower2438cdf2019-03-29 16:37:16 -070014393#ifdef MS_WINDOWS
14394/* bpo-36085: Helper functions for managing DLL search directories
14395 * on win32
14396 */
14397
14398typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory);
14399typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie);
14400
14401/*[clinic input]
14402os._add_dll_directory
14403
14404 path: path_t
14405
14406Add a path to the DLL search path.
14407
14408This search path is used when resolving dependencies for imported
14409extension modules (the module itself is resolved through sys.path),
14410and also by ctypes.
14411
14412Returns an opaque value that may be passed to os.remove_dll_directory
14413to remove this directory from the search path.
14414[clinic start generated code]*/
14415
14416static PyObject *
14417os__add_dll_directory_impl(PyObject *module, path_t *path)
14418/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/
14419{
14420 HMODULE hKernel32;
14421 PAddDllDirectory AddDllDirectory;
14422 DLL_DIRECTORY_COOKIE cookie = 0;
14423 DWORD err = 0;
14424
Saiyang Gou7514f4f2020-02-12 23:47:42 -080014425 if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) {
14426 return NULL;
14427 }
14428
Steve Dower2438cdf2019-03-29 16:37:16 -070014429 /* For Windows 7, we have to load this. As this will be a fairly
14430 infrequent operation, just do it each time. Kernel32 is always
14431 loaded. */
14432 Py_BEGIN_ALLOW_THREADS
14433 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14434 !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
14435 hKernel32, "AddDllDirectory")) ||
14436 !(cookie = (*AddDllDirectory)(path->wide))) {
14437 err = GetLastError();
14438 }
14439 Py_END_ALLOW_THREADS
14440
14441 if (err) {
14442 return win32_error_object_err("add_dll_directory",
14443 path->object, err);
14444 }
14445
14446 return PyCapsule_New(cookie, "DLL directory cookie", NULL);
14447}
14448
14449/*[clinic input]
14450os._remove_dll_directory
14451
14452 cookie: object
14453
14454Removes a path from the DLL search path.
14455
14456The parameter is an opaque value that was returned from
14457os.add_dll_directory. You can only remove directories that you added
14458yourself.
14459[clinic start generated code]*/
14460
14461static PyObject *
14462os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
14463/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/
14464{
14465 HMODULE hKernel32;
14466 PRemoveDllDirectory RemoveDllDirectory;
14467 DLL_DIRECTORY_COOKIE cookieValue;
14468 DWORD err = 0;
14469
14470 if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) {
14471 PyErr_SetString(PyExc_TypeError,
14472 "Provided cookie was not returned from os.add_dll_directory");
14473 return NULL;
14474 }
14475
14476 cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer(
14477 cookie, "DLL directory cookie");
14478
14479 /* For Windows 7, we have to load this. As this will be a fairly
14480 infrequent operation, just do it each time. Kernel32 is always
14481 loaded. */
14482 Py_BEGIN_ALLOW_THREADS
14483 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
14484 !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
14485 hKernel32, "RemoveDllDirectory")) ||
14486 !(*RemoveDllDirectory)(cookieValue)) {
14487 err = GetLastError();
14488 }
14489 Py_END_ALLOW_THREADS
14490
14491 if (err) {
14492 return win32_error_object_err("remove_dll_directory",
14493 NULL, err);
14494 }
14495
14496 if (PyCapsule_SetName(cookie, NULL)) {
14497 return NULL;
14498 }
14499
14500 Py_RETURN_NONE;
14501}
14502
14503#endif
Larry Hastings31826802013-10-19 00:09:25 -070014504
Victor Stinner65a796e2020-04-01 18:49:29 +020014505
14506/* Only check if WIFEXITED is available: expect that it comes
14507 with WEXITSTATUS, WIFSIGNALED, etc.
14508
14509 os.waitstatus_to_exitcode() is implemented in C and not in Python, so
14510 subprocess can safely call it during late Python finalization without
Victor Stinner62230712020-11-18 23:18:29 +010014511 risking that used os attributes were set to None by finalize_modules(). */
Victor Stinner65a796e2020-04-01 18:49:29 +020014512#if defined(WIFEXITED) || defined(MS_WINDOWS)
14513/*[clinic input]
14514os.waitstatus_to_exitcode
14515
Victor Stinner9bee32b2020-04-22 16:30:35 +020014516 status as status_obj: object
Victor Stinner65a796e2020-04-01 18:49:29 +020014517
14518Convert a wait status to an exit code.
14519
14520On Unix:
14521
14522* If WIFEXITED(status) is true, return WEXITSTATUS(status).
14523* If WIFSIGNALED(status) is true, return -WTERMSIG(status).
14524* Otherwise, raise a ValueError.
14525
14526On Windows, return status shifted right by 8 bits.
14527
14528On Unix, if the process is being traced or if waitpid() was called with
14529WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true.
14530This function must not be called if WIFSTOPPED(status) is true.
14531[clinic start generated code]*/
14532
14533static PyObject *
Victor Stinner9bee32b2020-04-22 16:30:35 +020014534os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj)
14535/*[clinic end generated code: output=db50b1b0ba3c7153 input=7fe2d7fdaea3db42]*/
Victor Stinner65a796e2020-04-01 18:49:29 +020014536{
14537#ifndef MS_WINDOWS
Victor Stinner9bee32b2020-04-22 16:30:35 +020014538 int status = _PyLong_AsInt(status_obj);
14539 if (status == -1 && PyErr_Occurred()) {
14540 return NULL;
14541 }
14542
Victor Stinner65a796e2020-04-01 18:49:29 +020014543 WAIT_TYPE wait_status;
14544 WAIT_STATUS_INT(wait_status) = status;
14545 int exitcode;
14546 if (WIFEXITED(wait_status)) {
14547 exitcode = WEXITSTATUS(wait_status);
14548 /* Sanity check to provide warranty on the function behavior.
14549 It should not occur in practice */
14550 if (exitcode < 0) {
14551 PyErr_Format(PyExc_ValueError, "invalid WEXITSTATUS: %i", exitcode);
14552 return NULL;
14553 }
14554 }
14555 else if (WIFSIGNALED(wait_status)) {
14556 int signum = WTERMSIG(wait_status);
14557 /* Sanity check to provide warranty on the function behavior.
14558 It should not occurs in practice */
14559 if (signum <= 0) {
14560 PyErr_Format(PyExc_ValueError, "invalid WTERMSIG: %i", signum);
14561 return NULL;
14562 }
14563 exitcode = -signum;
14564 } else if (WIFSTOPPED(wait_status)) {
14565 /* Status only received if the process is being traced
14566 or if waitpid() was called with WUNTRACED option. */
14567 int signum = WSTOPSIG(wait_status);
14568 PyErr_Format(PyExc_ValueError,
14569 "process stopped by delivery of signal %i",
14570 signum);
14571 return NULL;
14572 }
14573 else {
14574 PyErr_Format(PyExc_ValueError, "invalid wait status: %i", status);
14575 return NULL;
14576 }
14577 return PyLong_FromLong(exitcode);
14578#else
14579 /* Windows implementation: see os.waitpid() implementation
14580 which uses _cwait(). */
Victor Stinner9bee32b2020-04-22 16:30:35 +020014581 unsigned long long status = PyLong_AsUnsignedLongLong(status_obj);
14582 if (status == (unsigned long long)-1 && PyErr_Occurred()) {
14583 return NULL;
14584 }
14585
14586 unsigned long long exitcode = (status >> 8);
14587 /* ExitProcess() accepts an UINT type:
14588 reject exit code which doesn't fit in an UINT */
14589 if (exitcode > UINT_MAX) {
14590 PyErr_Format(PyExc_ValueError, "invalid exit code: %llu", exitcode);
14591 return NULL;
14592 }
14593 return PyLong_FromUnsignedLong((unsigned long)exitcode);
Victor Stinner65a796e2020-04-01 18:49:29 +020014594#endif
14595}
14596#endif
14597
14598
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014599static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070014600
14601 OS_STAT_METHODDEF
14602 OS_ACCESS_METHODDEF
14603 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014604 OS_CHDIR_METHODDEF
14605 OS_CHFLAGS_METHODDEF
14606 OS_CHMOD_METHODDEF
14607 OS_FCHMOD_METHODDEF
14608 OS_LCHMOD_METHODDEF
14609 OS_CHOWN_METHODDEF
14610 OS_FCHOWN_METHODDEF
14611 OS_LCHOWN_METHODDEF
14612 OS_LCHFLAGS_METHODDEF
14613 OS_CHROOT_METHODDEF
14614 OS_CTERMID_METHODDEF
14615 OS_GETCWD_METHODDEF
14616 OS_GETCWDB_METHODDEF
14617 OS_LINK_METHODDEF
14618 OS_LISTDIR_METHODDEF
14619 OS_LSTAT_METHODDEF
14620 OS_MKDIR_METHODDEF
14621 OS_NICE_METHODDEF
14622 OS_GETPRIORITY_METHODDEF
14623 OS_SETPRIORITY_METHODDEF
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000014624 OS_POSIX_SPAWN_METHODDEF
Joannah Nanjekye92b83222019-01-16 16:29:26 +030014625 OS_POSIX_SPAWNP_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014626 OS_READLINK_METHODDEF
Pablo Galindoaac4d032019-05-31 19:39:47 +010014627 OS_COPY_FILE_RANGE_METHODDEF
Pablo Galindoa57b3d32020-11-17 00:00:38 +000014628 OS_SPLICE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014629 OS_RENAME_METHODDEF
14630 OS_REPLACE_METHODDEF
14631 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014632 OS_SYMLINK_METHODDEF
14633 OS_SYSTEM_METHODDEF
14634 OS_UMASK_METHODDEF
14635 OS_UNAME_METHODDEF
14636 OS_UNLINK_METHODDEF
14637 OS_REMOVE_METHODDEF
14638 OS_UTIME_METHODDEF
14639 OS_TIMES_METHODDEF
14640 OS__EXIT_METHODDEF
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020014641 OS__FCOPYFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014642 OS_EXECV_METHODDEF
14643 OS_EXECVE_METHODDEF
14644 OS_SPAWNV_METHODDEF
14645 OS_SPAWNVE_METHODDEF
14646 OS_FORK1_METHODDEF
14647 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020014648 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014649 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
14650 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
14651 OS_SCHED_GETPARAM_METHODDEF
14652 OS_SCHED_GETSCHEDULER_METHODDEF
14653 OS_SCHED_RR_GET_INTERVAL_METHODDEF
14654 OS_SCHED_SETPARAM_METHODDEF
14655 OS_SCHED_SETSCHEDULER_METHODDEF
14656 OS_SCHED_YIELD_METHODDEF
14657 OS_SCHED_SETAFFINITY_METHODDEF
14658 OS_SCHED_GETAFFINITY_METHODDEF
14659 OS_OPENPTY_METHODDEF
14660 OS_FORKPTY_METHODDEF
14661 OS_GETEGID_METHODDEF
14662 OS_GETEUID_METHODDEF
14663 OS_GETGID_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014664 OS_GETGROUPLIST_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014665 OS_GETGROUPS_METHODDEF
14666 OS_GETPID_METHODDEF
14667 OS_GETPGRP_METHODDEF
14668 OS_GETPPID_METHODDEF
14669 OS_GETUID_METHODDEF
14670 OS_GETLOGIN_METHODDEF
14671 OS_KILL_METHODDEF
14672 OS_KILLPG_METHODDEF
14673 OS_PLOCK_METHODDEF
Steve Dowercc16be82016-09-08 10:35:16 -070014674 OS_STARTFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014675 OS_SETUID_METHODDEF
14676 OS_SETEUID_METHODDEF
14677 OS_SETREUID_METHODDEF
14678 OS_SETGID_METHODDEF
14679 OS_SETEGID_METHODDEF
14680 OS_SETREGID_METHODDEF
14681 OS_SETGROUPS_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014682 OS_INITGROUPS_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014683 OS_GETPGID_METHODDEF
14684 OS_SETPGRP_METHODDEF
14685 OS_WAIT_METHODDEF
14686 OS_WAIT3_METHODDEF
14687 OS_WAIT4_METHODDEF
14688 OS_WAITID_METHODDEF
14689 OS_WAITPID_METHODDEF
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -080014690 OS_PIDFD_OPEN_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014691 OS_GETSID_METHODDEF
14692 OS_SETSID_METHODDEF
14693 OS_SETPGID_METHODDEF
14694 OS_TCGETPGRP_METHODDEF
14695 OS_TCSETPGRP_METHODDEF
14696 OS_OPEN_METHODDEF
14697 OS_CLOSE_METHODDEF
14698 OS_CLOSERANGE_METHODDEF
14699 OS_DEVICE_ENCODING_METHODDEF
14700 OS_DUP_METHODDEF
14701 OS_DUP2_METHODDEF
14702 OS_LOCKF_METHODDEF
14703 OS_LSEEK_METHODDEF
14704 OS_READ_METHODDEF
14705 OS_READV_METHODDEF
14706 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014707 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014708 OS_WRITE_METHODDEF
14709 OS_WRITEV_METHODDEF
14710 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000014711 OS_PWRITEV_METHODDEF
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014712 OS_SENDFILE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014713 OS_FSTAT_METHODDEF
14714 OS_ISATTY_METHODDEF
14715 OS_PIPE_METHODDEF
14716 OS_PIPE2_METHODDEF
14717 OS_MKFIFO_METHODDEF
14718 OS_MKNOD_METHODDEF
14719 OS_MAJOR_METHODDEF
14720 OS_MINOR_METHODDEF
14721 OS_MAKEDEV_METHODDEF
14722 OS_FTRUNCATE_METHODDEF
14723 OS_TRUNCATE_METHODDEF
14724 OS_POSIX_FALLOCATE_METHODDEF
14725 OS_POSIX_FADVISE_METHODDEF
14726 OS_PUTENV_METHODDEF
14727 OS_UNSETENV_METHODDEF
14728 OS_STRERROR_METHODDEF
14729 OS_FCHDIR_METHODDEF
14730 OS_FSYNC_METHODDEF
14731 OS_SYNC_METHODDEF
14732 OS_FDATASYNC_METHODDEF
14733 OS_WCOREDUMP_METHODDEF
14734 OS_WIFCONTINUED_METHODDEF
14735 OS_WIFSTOPPED_METHODDEF
14736 OS_WIFSIGNALED_METHODDEF
14737 OS_WIFEXITED_METHODDEF
14738 OS_WEXITSTATUS_METHODDEF
14739 OS_WTERMSIG_METHODDEF
14740 OS_WSTOPSIG_METHODDEF
14741 OS_FSTATVFS_METHODDEF
14742 OS_STATVFS_METHODDEF
14743 OS_CONFSTR_METHODDEF
14744 OS_SYSCONF_METHODDEF
14745 OS_FPATHCONF_METHODDEF
14746 OS_PATHCONF_METHODDEF
14747 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030014748 OS__GETFULLPATHNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014749 OS__GETDISKUSAGE_METHODDEF
14750 OS__GETFINALPATHNAME_METHODDEF
14751 OS__GETVOLUMEPATHNAME_METHODDEF
14752 OS_GETLOADAVG_METHODDEF
14753 OS_URANDOM_METHODDEF
14754 OS_SETRESUID_METHODDEF
14755 OS_SETRESGID_METHODDEF
14756 OS_GETRESUID_METHODDEF
14757 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000014758
Larry Hastings2f936352014-08-05 14:04:04 +100014759 OS_GETXATTR_METHODDEF
14760 OS_SETXATTR_METHODDEF
14761 OS_REMOVEXATTR_METHODDEF
14762 OS_LISTXATTR_METHODDEF
14763
Serhiy Storchaka2b560312020-04-18 19:14:10 +030014764 OS_GET_TERMINAL_SIZE_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100014765 OS_CPU_COUNT_METHODDEF
14766 OS_GET_INHERITABLE_METHODDEF
14767 OS_SET_INHERITABLE_METHODDEF
14768 OS_GET_HANDLE_INHERITABLE_METHODDEF
14769 OS_SET_HANDLE_INHERITABLE_METHODDEF
Serhiy Storchaka12a69db2018-09-17 15:38:27 +030014770 OS_GET_BLOCKING_METHODDEF
14771 OS_SET_BLOCKING_METHODDEF
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020014772 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070014773 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070014774 OS_GETRANDOM_METHODDEF
Zackery Spytz43fdbd22019-05-29 13:57:07 -060014775 OS_MEMFD_CREATE_METHODDEF
Christian Heimescd9fed62020-11-13 19:48:52 +010014776 OS_EVENTFD_METHODDEF
14777 OS_EVENTFD_READ_METHODDEF
14778 OS_EVENTFD_WRITE_METHODDEF
Steve Dower2438cdf2019-03-29 16:37:16 -070014779 OS__ADD_DLL_DIRECTORY_METHODDEF
14780 OS__REMOVE_DLL_DIRECTORY_METHODDEF
Victor Stinner65a796e2020-04-01 18:49:29 +020014781 OS_WAITSTATUS_TO_EXITCODE_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000014782 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014783};
14784
Barry Warsaw4a342091996-12-19 23:50:02 +000014785static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014786all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000014787{
Guido van Rossum94f6f721999-01-06 18:42:14 +000014788#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014789 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014790#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014791#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014792 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014793#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014794#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014795 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014796#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000014797#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014798 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014799#endif
Fred Drakec9680921999-12-13 16:37:25 +000014800#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014801 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000014802#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014803#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014804 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000014805#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014806#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014807 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014808#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014809#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014810 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014811#endif
Fred Drake106c1a02002-04-23 15:58:02 +000014812#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014813 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000014814#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000014815#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014816 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014817#endif
14818#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014819 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014820#endif
14821#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014822 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014823#endif
14824#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014825 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014826#endif
14827#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014828 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014829#endif
14830#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014831 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014832#endif
14833#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014834 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014835#endif
14836#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014837 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014838#endif
14839#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014840 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014841#endif
14842#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014843 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014844#endif
14845#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014846 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014847#endif
14848#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014849 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014850#endif
14851#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014852 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000014853#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000014854#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014855 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014856#endif
14857#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014858 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000014859#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014860#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014861 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014862#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014863#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014864 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014865#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014866#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000014867#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014868 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014869#endif
14870#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014871 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000014872#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020014873#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014874#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014875 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014876#endif
14877#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014878 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014879#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014880#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014881 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050014882#endif
Jesus Ceacf381202012-04-24 20:44:40 +020014883#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014884 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020014885#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020014886#ifdef O_TMPFILE
14887 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
14888#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014889#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014890 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014891#endif
14892#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014893 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014894#endif
14895#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014896 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000014897#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020014898#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014899 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020014900#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014901#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014902 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014903#endif
Dong-hee Naf917c242021-02-04 08:32:55 +090014904#ifdef O_EVTONLY
14905 if (PyModule_AddIntMacro(m, O_EVTONLY)) return -1;
14906#endif
14907#ifdef O_FSYNC
14908 if (PyModule_AddIntMacro(m, O_FSYNC)) return -1;
14909#endif
14910#ifdef O_SYMLINK
14911 if (PyModule_AddIntMacro(m, O_SYMLINK)) return -1;
14912#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014913
Jesus Cea94363612012-06-22 18:32:07 +020014914#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014915 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014916#endif
14917#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014918 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020014919#endif
14920
Tim Peters5aa91602002-01-30 05:46:57 +000014921/* MS Windows */
14922#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000014923 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014924 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014925#endif
14926#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000014927 /* Optimize for short life (keep in memory). */
14928 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014929 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014930#endif
14931#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000014932 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014933 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014934#endif
14935#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000014936 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014937 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014938#endif
14939#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000014940 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014941 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000014942#endif
14943
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014944/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014945#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000014946 /* Send a SIGIO signal whenever input or output
14947 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014948 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000014949#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014950#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000014951 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014952 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014953#endif
14954#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000014955 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014956 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014957#endif
14958#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000014959 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014960 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000014961#endif
Dong-hee Naf917c242021-02-04 08:32:55 +090014962#ifdef O_NOFOLLOW_ANY
14963 if (PyModule_AddIntMacro(m, O_NOFOLLOW_ANY)) return -1;
14964#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020014965#ifdef O_NOLINKS
14966 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014967 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020014968#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014969#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000014970 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014971 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000014972#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000014973
Victor Stinner8c62be82010-05-06 00:08:46 +000014974 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014975#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014976 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014977#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014978#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014979 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014980#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014981#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014982 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014983#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014984#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014985 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014986#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014987#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014988 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014989#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014990#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014991 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014992#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014993#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014994 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014995#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014996#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020014997 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000014998#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000014999#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015000 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015001#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015002#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015003 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015004#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015005#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015006 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015007#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015008#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015009 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015010#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015011#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015012 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015013#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015014#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015015 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015016#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015017#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015018 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015019#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015020#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015021 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015022#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015023#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015024 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000015025#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000015026
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000015027 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015028#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015029 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015030#endif /* ST_RDONLY */
15031#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015032 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000015033#endif /* ST_NOSUID */
15034
doko@ubuntu.comca616a22013-12-08 15:23:07 +010015035 /* GNU extensions */
15036#ifdef ST_NODEV
15037 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
15038#endif /* ST_NODEV */
15039#ifdef ST_NOEXEC
15040 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
15041#endif /* ST_NOEXEC */
15042#ifdef ST_SYNCHRONOUS
15043 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
15044#endif /* ST_SYNCHRONOUS */
15045#ifdef ST_MANDLOCK
15046 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
15047#endif /* ST_MANDLOCK */
15048#ifdef ST_WRITE
15049 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
15050#endif /* ST_WRITE */
15051#ifdef ST_APPEND
15052 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
15053#endif /* ST_APPEND */
15054#ifdef ST_NOATIME
15055 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
15056#endif /* ST_NOATIME */
15057#ifdef ST_NODIRATIME
15058 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
15059#endif /* ST_NODIRATIME */
15060#ifdef ST_RELATIME
15061 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
15062#endif /* ST_RELATIME */
15063
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015064 /* FreeBSD sendfile() constants */
15065#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015066 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015067#endif
15068#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015069 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015070#endif
15071#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015072 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000015073#endif
15074
Ross Lagerwall7807c352011-03-17 20:20:30 +020015075 /* constants for posix_fadvise */
15076#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015077 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015078#endif
15079#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015080 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015081#endif
15082#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015083 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015084#endif
15085#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015086 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015087#endif
15088#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015089 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015090#endif
15091#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015092 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015093#endif
15094
15095 /* constants for waitid */
15096#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015097 if (PyModule_AddIntMacro(m, P_PID)) return -1;
15098 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
15099 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Benjamin Peterson5c0c3252019-11-05 21:58:31 -080015100#ifdef P_PIDFD
15101 if (PyModule_AddIntMacro(m, P_PIDFD)) return -1;
15102#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015103#endif
15104#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015105 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015106#endif
15107#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015108 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015109#endif
15110#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015111 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015112#endif
15113#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015114 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015115#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015116#ifdef CLD_KILLED
15117 if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1;
15118#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015119#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015120 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015121#endif
15122#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015123 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015124#endif
Dong-hee Na2eba6ad2019-10-21 16:01:05 +090015125#ifdef CLD_STOPPED
15126 if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1;
15127#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020015128#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015129 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015130#endif
15131
15132 /* constants for lockf */
15133#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015134 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015135#endif
15136#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015137 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015138#endif
15139#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015140 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015141#endif
15142#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015143 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015144#endif
15145
Pablo Galindo4defba32018-01-27 16:16:37 +000015146#ifdef RWF_DSYNC
15147 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
15148#endif
15149#ifdef RWF_HIPRI
15150 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
15151#endif
15152#ifdef RWF_SYNC
15153 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
15154#endif
15155#ifdef RWF_NOWAIT
15156 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
15157#endif
YoSTEALTH76ef2552020-05-27 15:32:22 -060015158#ifdef RWF_APPEND
15159 if (PyModule_AddIntConstant(m, "RWF_APPEND", RWF_APPEND)) return -1;
15160#endif
Pablo Galindo4defba32018-01-27 16:16:37 +000015161
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015162/* constants for splice */
Pablo Galindo2a9eddf2020-11-17 19:57:49 +000015163#if defined(HAVE_SPLICE) && defined(__linux__)
Pablo Galindoa57b3d32020-11-17 00:00:38 +000015164 if (PyModule_AddIntConstant(m, "SPLICE_F_MOVE", SPLICE_F_MOVE)) return -1;
15165 if (PyModule_AddIntConstant(m, "SPLICE_F_NONBLOCK", SPLICE_F_NONBLOCK)) return -1;
15166 if (PyModule_AddIntConstant(m, "SPLICE_F_MORE", SPLICE_F_MORE)) return -1;
15167#endif
15168
Pablo Galindo6c6ddf92018-01-29 01:56:10 +000015169/* constants for posix_spawn */
15170#ifdef HAVE_POSIX_SPAWN
15171 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1;
15172 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1;
15173 if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1;
15174#endif
15175
pxinwrf2d7ac72019-05-21 18:46:37 +080015176#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015177 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
15178 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015179 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
pxinwrf2d7ac72019-05-21 18:46:37 +080015180#endif
15181#ifdef HAVE_SPAWNV
15182 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015183 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000015184#endif
15185
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015186#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015187#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015188 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015189#endif
15190#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015191 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015192#endif
15193#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015194 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070015195#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015196#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080015197 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015198#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015199#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015200 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015201#endif
15202#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015203 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015204#endif
15205#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015206 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015207#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015208#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015209 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015210#endif
15211#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015212 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015213#endif
15214#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015215 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015216#endif
15217#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015218 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020015219#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015220#endif
15221
Benjamin Peterson9428d532011-09-14 11:45:52 -040015222#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015223 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
15224 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
15225 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040015226#endif
15227
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015228#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015229 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015230#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015231#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015232 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015233#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015234#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015235 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015236#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015237#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015238 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015239#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015240#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015241 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015242#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015243#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015244 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015245#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030015246#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020015247 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020015248#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010015249#if HAVE_DECL_RTLD_MEMBER
15250 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
15251#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020015252
Victor Stinner9b1f4742016-09-06 16:18:52 -070015253#ifdef HAVE_GETRANDOM_SYSCALL
15254 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
15255 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
15256#endif
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015257#ifdef HAVE_MEMFD_CREATE
15258 if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1;
15259 if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1;
15260#ifdef MFD_HUGETLB
15261 if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015262#endif
15263#ifdef MFD_HUGE_SHIFT
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015264 if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015265#endif
15266#ifdef MFD_HUGE_MASK
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015267 if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015268#endif
15269#ifdef MFD_HUGE_64KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015270 if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015271#endif
15272#ifdef MFD_HUGE_512KB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015273 if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015274#endif
15275#ifdef MFD_HUGE_1MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015276 if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015277#endif
15278#ifdef MFD_HUGE_2MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015279 if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015280#endif
15281#ifdef MFD_HUGE_8MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015282 if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015283#endif
15284#ifdef MFD_HUGE_16MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015285 if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015286#endif
15287#ifdef MFD_HUGE_32MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015288 if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015289#endif
15290#ifdef MFD_HUGE_256MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015291 if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015292#endif
15293#ifdef MFD_HUGE_512MB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015294 if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015295#endif
15296#ifdef MFD_HUGE_1GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015297 if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015298#endif
15299#ifdef MFD_HUGE_2GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015300 if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1;
Zackery Spytze70bfa952019-05-29 14:43:50 -060015301#endif
15302#ifdef MFD_HUGE_16GB
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015303 if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1;
15304#endif
Christian Heimescd9fed62020-11-13 19:48:52 +010015305#endif /* HAVE_MEMFD_CREATE */
15306
15307#ifdef HAVE_EVENTFD
15308 if (PyModule_AddIntMacro(m, EFD_CLOEXEC)) return -1;
15309 if (PyModule_AddIntMacro(m, EFD_NONBLOCK)) return -1;
15310 if (PyModule_AddIntMacro(m, EFD_SEMAPHORE)) return -1;
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015311#endif
Victor Stinner9b1f4742016-09-06 16:18:52 -070015312
Giampaolo Rodola4a172cc2018-06-12 23:04:50 +020015313#if defined(__APPLE__)
15314 if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1;
15315#endif
15316
Steve Dower2438cdf2019-03-29 16:37:16 -070015317#ifdef MS_WINDOWS
15318 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1;
15319 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1;
15320 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1;
15321 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1;
15322 if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1;
15323#endif
15324
Victor Stinner8c62be82010-05-06 00:08:46 +000015325 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000015326}
15327
15328
Ronald Oussoren41761932020-11-08 10:05:27 +010015329
15330#define PROBE(name, test) \
15331 static int name(void) \
15332 { \
15333 if (test) { \
15334 return 1; \
15335 } else { \
15336 return 0; \
15337 } \
15338 }
15339
15340#ifdef HAVE_FSTATAT
15341PROBE(probe_fstatat, HAVE_FSTATAT_RUNTIME)
15342#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070015343
15344#ifdef HAVE_FACCESSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015345PROBE(probe_faccessat, HAVE_FACCESSAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015346#endif
15347
15348#ifdef HAVE_FCHMODAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015349PROBE(probe_fchmodat, HAVE_FCHMODAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015350#endif
15351
Larry Hastings00964ed2013-08-12 13:49:30 -040015352#ifdef HAVE_FCHOWNAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015353PROBE(probe_fchownat, HAVE_FCHOWNAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015354#endif
15355
15356#ifdef HAVE_LINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015357PROBE(probe_linkat, HAVE_LINKAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015358#endif
15359
Ronald Oussoren41761932020-11-08 10:05:27 +010015360#ifdef HAVE_FDOPENDIR
15361PROBE(probe_fdopendir, HAVE_FDOPENDIR_RUNTIME)
Zackery Spytz43fdbd22019-05-29 13:57:07 -060015362#endif
15363
Larry Hastings9cf065c2012-06-22 16:30:09 -070015364#ifdef HAVE_MKDIRAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015365PROBE(probe_mkdirat, HAVE_MKDIRAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015366#endif
15367
15368#ifdef HAVE_RENAMEAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015369PROBE(probe_renameat, HAVE_RENAMEAT_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015370#endif
15371
15372#ifdef HAVE_UNLINKAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015373PROBE(probe_unlinkat, HAVE_UNLINKAT_RUNTIME)
15374#endif
15375
15376#ifdef HAVE_OPENAT
15377PROBE(probe_openat, HAVE_OPENAT_RUNTIME)
15378#endif
15379
15380#ifdef HAVE_READLINKAT
15381PROBE(probe_readlinkat, HAVE_READLINKAT_RUNTIME)
15382#endif
15383
15384#ifdef HAVE_SYMLINKAT
15385PROBE(probe_symlinkat, HAVE_SYMLINKAT_RUNTIME)
15386#endif
15387
15388#ifdef HAVE_FUTIMENS
15389PROBE(probe_futimens, HAVE_FUTIMENS_RUNTIME)
Larry Hastings9cf065c2012-06-22 16:30:09 -070015390#endif
15391
15392#ifdef HAVE_UTIMENSAT
Ronald Oussoren41761932020-11-08 10:05:27 +010015393PROBE(probe_utimensat, HAVE_UTIMENSAT_RUNTIME)
15394#endif
15395
15396
15397
15398
15399static const struct have_function {
15400 const char * const label;
15401 int (*probe)(void);
15402} have_functions[] = {
15403
Christian Heimescd9fed62020-11-13 19:48:52 +010015404#ifdef HAVE_EVENTFD
15405 {"HAVE_EVENTFD", NULL},
15406#endif
15407
Ronald Oussoren41761932020-11-08 10:05:27 +010015408#ifdef HAVE_FACCESSAT
15409 { "HAVE_FACCESSAT", probe_faccessat },
15410#endif
15411
15412#ifdef HAVE_FCHDIR
15413 { "HAVE_FCHDIR", NULL },
15414#endif
15415
15416#ifdef HAVE_FCHMOD
15417 { "HAVE_FCHMOD", NULL },
15418#endif
15419
15420#ifdef HAVE_FCHMODAT
15421 { "HAVE_FCHMODAT", probe_fchmodat },
15422#endif
15423
15424#ifdef HAVE_FCHOWN
15425 { "HAVE_FCHOWN", NULL },
15426#endif
15427
15428#ifdef HAVE_FCHOWNAT
15429 { "HAVE_FCHOWNAT", probe_fchownat },
15430#endif
15431
15432#ifdef HAVE_FEXECVE
15433 { "HAVE_FEXECVE", NULL },
15434#endif
15435
15436#ifdef HAVE_FDOPENDIR
15437 { "HAVE_FDOPENDIR", probe_fdopendir },
15438#endif
15439
15440#ifdef HAVE_FPATHCONF
15441 { "HAVE_FPATHCONF", NULL },
15442#endif
15443
15444#ifdef HAVE_FSTATAT
15445 { "HAVE_FSTATAT", probe_fstatat },
15446#endif
15447
15448#ifdef HAVE_FSTATVFS
15449 { "HAVE_FSTATVFS", NULL },
15450#endif
15451
15452#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
15453 { "HAVE_FTRUNCATE", NULL },
15454#endif
15455
15456#ifdef HAVE_FUTIMENS
15457 { "HAVE_FUTIMENS", probe_futimens },
15458#endif
15459
15460#ifdef HAVE_FUTIMES
15461 { "HAVE_FUTIMES", NULL },
15462#endif
15463
15464#ifdef HAVE_FUTIMESAT
15465 { "HAVE_FUTIMESAT", NULL },
15466#endif
15467
15468#ifdef HAVE_LINKAT
15469 { "HAVE_LINKAT", probe_linkat },
15470#endif
15471
15472#ifdef HAVE_LCHFLAGS
15473 { "HAVE_LCHFLAGS", NULL },
15474#endif
15475
15476#ifdef HAVE_LCHMOD
15477 { "HAVE_LCHMOD", NULL },
15478#endif
15479
15480#ifdef HAVE_LCHOWN
15481 { "HAVE_LCHOWN", NULL },
15482#endif
15483
15484#ifdef HAVE_LSTAT
15485 { "HAVE_LSTAT", NULL },
15486#endif
15487
15488#ifdef HAVE_LUTIMES
15489 { "HAVE_LUTIMES", NULL },
15490#endif
15491
15492#ifdef HAVE_MEMFD_CREATE
15493 { "HAVE_MEMFD_CREATE", NULL },
15494#endif
15495
15496#ifdef HAVE_MKDIRAT
15497 { "HAVE_MKDIRAT", probe_mkdirat },
15498#endif
15499
15500#ifdef HAVE_MKFIFOAT
15501 { "HAVE_MKFIFOAT", NULL },
15502#endif
15503
15504#ifdef HAVE_MKNODAT
15505 { "HAVE_MKNODAT", NULL },
15506#endif
15507
15508#ifdef HAVE_OPENAT
15509 { "HAVE_OPENAT", probe_openat },
15510#endif
15511
15512#ifdef HAVE_READLINKAT
15513 { "HAVE_READLINKAT", probe_readlinkat },
15514#endif
15515
15516#ifdef HAVE_RENAMEAT
15517 { "HAVE_RENAMEAT", probe_renameat },
15518#endif
15519
15520#ifdef HAVE_SYMLINKAT
15521 { "HAVE_SYMLINKAT", probe_symlinkat },
15522#endif
15523
15524#ifdef HAVE_UNLINKAT
15525 { "HAVE_UNLINKAT", probe_unlinkat },
15526#endif
15527
15528#ifdef HAVE_UTIMENSAT
15529 { "HAVE_UTIMENSAT", probe_utimensat },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015530#endif
15531
15532#ifdef MS_WINDOWS
Ronald Oussoren41761932020-11-08 10:05:27 +010015533 { "MS_WINDOWS", NULL },
Larry Hastings9cf065c2012-06-22 16:30:09 -070015534#endif
15535
Ronald Oussoren41761932020-11-08 10:05:27 +010015536 { NULL, NULL }
Larry Hastings9cf065c2012-06-22 16:30:09 -070015537};
15538
15539
Victor Stinner1c2fa782020-05-10 11:05:29 +020015540static int
15541posixmodule_exec(PyObject *m)
Guido van Rossumb6775db1994-08-01 11:34:53 +000015542{
Victor Stinner97f33c32020-05-14 18:05:58 +020015543 _posixstate *state = get_posix_state(m);
Tim Peters5aa91602002-01-30 05:46:57 +000015544
Ronald Oussoren41761932020-11-08 10:05:27 +010015545#if defined(HAVE_PWRITEV)
15546 if (HAVE_PWRITEV_RUNTIME) {} else {
15547 PyObject* dct = PyModule_GetDict(m);
15548
15549 if (dct == NULL) {
15550 return -1;
15551 }
15552
15553 if (PyDict_DelItemString(dct, "pwritev") == -1) {
15554 PyErr_Clear();
15555 }
15556 if (PyDict_DelItemString(dct, "preadv") == -1) {
15557 PyErr_Clear();
15558 }
15559 }
15560#endif
15561
Victor Stinner8c62be82010-05-06 00:08:46 +000015562 /* Initialize environ dictionary */
Victor Stinner97f33c32020-05-14 18:05:58 +020015563 PyObject *v = convertenviron();
Victor Stinner8c62be82010-05-06 00:08:46 +000015564 Py_XINCREF(v);
15565 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015566 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015567 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000015568
Victor Stinner8c62be82010-05-06 00:08:46 +000015569 if (all_ins(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015570 return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000015571
Victor Stinner8c62be82010-05-06 00:08:46 +000015572 if (setup_confname_tables(m))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015573 return -1;
Fred Drakebec628d1999-12-15 18:31:10 +000015574
Victor Stinner8c62be82010-05-06 00:08:46 +000015575 Py_INCREF(PyExc_OSError);
15576 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000015577
Ross Lagerwall7807c352011-03-17 20:20:30 +020015578#if defined(HAVE_WAITID) && !defined(__APPLE__)
Eddie Elizondob3966632019-11-05 07:16:14 -080015579 waitid_result_desc.name = MODNAME ".waitid_result";
15580 PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
15581 if (WaitidResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015582 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015583 }
15584 Py_INCREF(WaitidResultType);
15585 PyModule_AddObject(m, "waitid_result", WaitidResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015586 state->WaitidResultType = WaitidResultType;
Ross Lagerwall7807c352011-03-17 20:20:30 +020015587#endif
15588
Eddie Elizondob3966632019-11-05 07:16:14 -080015589 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
15590 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
15591 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
15592 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
15593 PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc);
15594 if (StatResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015595 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015596 }
15597 Py_INCREF(StatResultType);
15598 PyModule_AddObject(m, "stat_result", StatResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015599 state->StatResultType = StatResultType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015600 structseq_new = ((PyTypeObject *)StatResultType)->tp_new;
15601 ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015602
Eddie Elizondob3966632019-11-05 07:16:14 -080015603 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
15604 PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc);
15605 if (StatVFSResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015606 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015607 }
15608 Py_INCREF(StatVFSResultType);
15609 PyModule_AddObject(m, "statvfs_result", StatVFSResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015610 state->StatVFSResultType = StatVFSResultType;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015611#ifdef NEED_TICKS_PER_SECOND
15612# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Eddie Elizondob3966632019-11-05 07:16:14 -080015613 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015614# elif defined(HZ)
Eddie Elizondob3966632019-11-05 07:16:14 -080015615 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015616# else
Eddie Elizondob3966632019-11-05 07:16:14 -080015617 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000015618# endif
15619#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050015620
William Orr81574b82018-10-01 22:19:56 -070015621#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
Eddie Elizondob3966632019-11-05 07:16:14 -080015622 sched_param_desc.name = MODNAME ".sched_param";
15623 PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc);
15624 if (SchedParamType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015625 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +000015626 }
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015627 Py_INCREF(SchedParamType);
Eddie Elizondob3966632019-11-05 07:16:14 -080015628 PyModule_AddObject(m, "sched_param", SchedParamType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015629 state->SchedParamType = SchedParamType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015630 ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param;
Benjamin Petersone3298dd2011-08-02 18:40:46 -050015631#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000015632
Eddie Elizondob3966632019-11-05 07:16:14 -080015633 /* initialize TerminalSize_info */
15634 PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc);
15635 if (TerminalSizeType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015636 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015637 }
15638 Py_INCREF(TerminalSizeType);
15639 PyModule_AddObject(m, "terminal_size", TerminalSizeType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015640 state->TerminalSizeType = TerminalSizeType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015641
15642 /* initialize scandir types */
Victor Stinner1c2fa782020-05-10 11:05:29 +020015643 PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015644 if (ScandirIteratorType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015645 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015646 }
Victor Stinner97f33c32020-05-14 18:05:58 +020015647 state->ScandirIteratorType = ScandirIteratorType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015648
Victor Stinner1c2fa782020-05-10 11:05:29 +020015649 PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL);
Eddie Elizondob3966632019-11-05 07:16:14 -080015650 if (DirEntryType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015651 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015652 }
15653 Py_INCREF(DirEntryType);
15654 PyModule_AddObject(m, "DirEntry", DirEntryType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015655 state->DirEntryType = DirEntryType;
Eddie Elizondob3966632019-11-05 07:16:14 -080015656
Larry Hastings605a62d2012-06-24 04:33:36 -070015657 times_result_desc.name = MODNAME ".times_result";
Eddie Elizondob3966632019-11-05 07:16:14 -080015658 PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(&times_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015659 if (TimesResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015660 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015661 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015662 Py_INCREF(TimesResultType);
15663 PyModule_AddObject(m, "times_result", TimesResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015664 state->TimesResultType = TimesResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015665
Eddie Elizondob3966632019-11-05 07:16:14 -080015666 PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015667 if (UnameResultType == NULL) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015668 return -1;
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015669 }
Eddie Elizondob3966632019-11-05 07:16:14 -080015670 Py_INCREF(UnameResultType);
Eddie Elizondo474eedf2018-11-13 04:09:31 -080015671 PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType);
Victor Stinner97f33c32020-05-14 18:05:58 +020015672 state->UnameResultType = (PyObject *)UnameResultType;
Larry Hastings605a62d2012-06-24 04:33:36 -070015673
Victor Stinner97f33c32020-05-14 18:05:58 +020015674 if ((state->billion = PyLong_FromLong(1000000000)) == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015675 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015676#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Victor Stinner97f33c32020-05-14 18:05:58 +020015677 state->struct_rusage = PyUnicode_InternFromString("struct_rusage");
15678 if (state->struct_rusage == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015679 return -1;
Eddie Elizondob3966632019-11-05 07:16:14 -080015680#endif
Victor Stinner97f33c32020-05-14 18:05:58 +020015681 state->st_mode = PyUnicode_InternFromString("st_mode");
15682 if (state->st_mode == NULL)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015683 return -1;
Larry Hastings6fe20b32012-04-19 15:07:49 -070015684
Larry Hastings9cf065c2012-06-22 16:30:09 -070015685 /* suppress "function not used" warnings */
15686 {
15687 int ignored;
15688 fd_specified("", -1);
15689 follow_symlinks_specified("", 1);
15690 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
15691 dir_fd_converter(Py_None, &ignored);
15692 dir_fd_unavailable(Py_None, &ignored);
15693 }
15694
15695 /*
15696 * provide list of locally available functions
15697 * so os.py can populate support_* lists
15698 */
Victor Stinner97f33c32020-05-14 18:05:58 +020015699 PyObject *list = PyList_New(0);
15700 if (!list) {
Victor Stinner1c2fa782020-05-10 11:05:29 +020015701 return -1;
Victor Stinner97f33c32020-05-14 18:05:58 +020015702 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015703 for (const struct have_function *trace = have_functions; trace->label; trace++) {
15704 PyObject *unicode;
15705 if (trace->probe && !trace->probe()) continue;
15706 unicode = PyUnicode_DecodeASCII(trace->label, strlen(trace->label), NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -070015707 if (!unicode)
Victor Stinner1c2fa782020-05-10 11:05:29 +020015708 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015709 if (PyList_Append(list, unicode))
Victor Stinner1c2fa782020-05-10 11:05:29 +020015710 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -070015711 Py_DECREF(unicode);
15712 }
Ronald Oussoren41761932020-11-08 10:05:27 +010015713
Larry Hastings9cf065c2012-06-22 16:30:09 -070015714 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040015715
Victor Stinner1c2fa782020-05-10 11:05:29 +020015716 return 0;
15717}
15718
15719
15720static PyModuleDef_Slot posixmodile_slots[] = {
15721 {Py_mod_exec, posixmodule_exec},
15722 {0, NULL}
15723};
15724
15725static struct PyModuleDef posixmodule = {
15726 PyModuleDef_HEAD_INIT,
15727 .m_name = MODNAME,
15728 .m_doc = posix__doc__,
15729 .m_size = sizeof(_posixstate),
15730 .m_methods = posix_methods,
15731 .m_slots = posixmodile_slots,
15732 .m_traverse = _posix_traverse,
15733 .m_clear = _posix_clear,
15734 .m_free = _posix_free,
15735};
15736
15737PyMODINIT_FUNC
15738INITFUNC(void)
15739{
15740 return PyModuleDef_Init(&posixmodule);
Guido van Rossumb6775db1994-08-01 11:34:53 +000015741}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000015742
15743#ifdef __cplusplus
15744}
15745#endif